<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cloud Deployment Guides on Grafana Labs</title><link>https://grafana.com/docs/loki/v3.7.x/setup/install/helm/deployment-guides/</link><description>Recent content in Cloud Deployment Guides on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/loki/v3.7.x/setup/install/helm/deployment-guides/index.xml" rel="self" type="application/rss+xml"/><item><title>Deploy the Loki Helm chart on AWS</title><link>https://grafana.com/docs/loki/v3.7.x/setup/install/helm/deployment-guides/aws/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.x/setup/install/helm/deployment-guides/aws/</guid><content><![CDATA[&lt;h1 id=&#34;deploy-the-loki-helm-chart-on-aws&#34;&gt;Deploy the Loki Helm chart on AWS&lt;/h1&gt;
&lt;p&gt;This guide shows how to deploy a minimally viable Loki in &lt;strong&gt;microservice&lt;/strong&gt; mode on AWS using the Helm chart. To run through this guide, we expect you to have the necessary tools and permissions to deploy resources on AWS, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Full access to EKS (Amazon Elastic Kubernetes Service)&lt;/li&gt;
&lt;li&gt;Full access to S3 (Amazon Simple Storage Service)&lt;/li&gt;
&lt;li&gt;Sufficient permissions to create IAM (Identity Access Management) roles and policies&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are two methods for authenticating and connecting Loki to AWS S3. We will guide you through the recommended method of granting access via an IAM role.&lt;/p&gt;
&lt;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#39;https://www.youtube.com/embed/5lXmWmofqwM&#39; title=&#34;YouTube video player&#34; frameborder=&#34;0&#34; allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; allowfullscreen&gt;&lt;/iframe&gt;
&lt;h2 id=&#34;considerations&#34;&gt;Considerations&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-caution&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Caution&lt;/p&gt;&lt;p&gt;This guide was accurate at the time it was last updated on &lt;strong&gt;31st October, 2024&lt;/strong&gt;.  As cloud providers frequently update their services and offerings, as a best practice, you should refer to the &lt;a href=&#34;https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;AWS S3 documentation&lt;/a&gt; before creating your buckets and assigning roles.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;IAM Role:&lt;/strong&gt; The IAM role created in this guide is a basic role that allows Loki to read and write to the S3 bucket. You may wish to add more granular permissions based on your requirements.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Authentication:&lt;/strong&gt; Grafana Loki comes with a basic authentication layer. The Loki gateway (NGINX) is exposed to the internet using basic authentication in this example. NGINX can also be replaced with other open-source reverse proxies. Refer to 
    &lt;a href=&#34;/docs/loki/v3.7.x/operations/authentication/&#34;&gt;Authentication&lt;/a&gt; for more information.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Retention:&lt;/strong&gt; The retention period is set to 28 days in the &lt;code&gt;values.yaml&lt;/code&gt; file. You may wish to adjust this based on your requirements.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Costs:&lt;/strong&gt; Running Loki on AWS will incur costs. Make sure to monitor your usage and costs to avoid any unexpected bills. In this guide we have used a simple EKS cluster with 3 nodes and m5.xlarge instances. You may wish to adjust the instance types and number of nodes based on your workload.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Helm 3 or above. Refer to &lt;a href=&#34;https://helm.sh/docs/intro/install/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Installing Helm&lt;/a&gt;. This should be installed on your local machine.&lt;/li&gt;
&lt;li&gt;A running Kubernetes cluster on AWS. A simple way to get started is by using EKSctl. Refer to &lt;a href=&#34;https://eksctl.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Getting started with EKSctl&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Kubectl installed on your local machine. Refer to &lt;a href=&#34;https://kubernetes.io/docs/tasks/tools/install-kubectl/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Install and Set Up kubectl&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;(Optional) AWS CLI installed on your local machine. Refer to &lt;a href=&#34;https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Installing the AWS CLI&lt;/a&gt;. This is required if you plan to use EKSctl to create the EKS cluster and modify the IAM roles and policies locally.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;eks-minimum-requirements&#34;&gt;EKS Minimum Requirements&lt;/h3&gt;


&lt;div class=&#34;admonition admonition-caution&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Caution&lt;/p&gt;&lt;p&gt;These EKS requirements are the minimum specification needed to deploy Loki using this guide. You may wish to adjust plugins and instance types based on your AWS environment and workload. &lt;strong&gt;If you choose to do so, we cannot guarantee that this sample configuration will still meet your needs.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this guide, we deploy Loki using &lt;code&gt;m5.xlarge&lt;/code&gt; instances. This is a instance type that should work for most scenarios. However, you can modify the instance types and count based on your specific needs.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;The minimum requirements for deploying Loki on EKS are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes version &lt;code&gt;1.30&lt;/code&gt; or above.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;3&lt;/code&gt; nodes for the EKS cluster.&lt;/li&gt;
&lt;li&gt;Instance type depends on your workload. A good starting point for a production cluster is &lt;code&gt;m7i.2xlarge&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is the EKSctl cluster configuration file used in this guide:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;# A simple example of ClusterConfig object:
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: &amp;lt;INSERT_CLUSTER_NAME&amp;gt;
  region: &amp;lt;INSERT_REGION_FOR_CLUSTER&amp;gt;
  version: &amp;#34;1.31&amp;#34;

iam:
  withOIDC: true

addons:
  - name: aws-ebs-csi-driver

managedNodeGroups:
  - name: loki-workers
    instanceType: m7i.2xlarge
    desiredCapacity: 3
    minSize: 2
    maxSize: 3
    amiFamily: AmazonLinux2023
    iam:
      withAddonPolicies:
        ebs: true
    volumeSize: 80
    volumeType: gp3
    ebsOptimized: true&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The following plugins must also be installed within the EKS cluster:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Amazon EBS CSI Driver&lt;/strong&gt;: Enables Kubernetes to dynamically provision and manage EBS volumes as persistent storage for applications. We use this to provision the node volumes for Loki.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CoreDNS&lt;/strong&gt;: Provides internal DNS service for Kubernetes clusters, ensuring that services and pods can communicate with each other using DNS names.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;kube-proxy&lt;/strong&gt;: Maintains network rules on nodes, enabling communication between pods and services within the cluster.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You must also install an &lt;strong&gt;OIDC (OpenID Connect) provider&lt;/strong&gt; on the EKS cluster. This is required for the IAM roles and policies to work correctly. If you are using EKSctl, you can install the OIDC provider using the following command:&lt;/p&gt;


&lt;div class=&#34;admonition admonition-tip&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Tip&lt;/p&gt;&lt;p&gt;If you used the above EKSctl configuration file to create the cluster, you do not need to run this command. The OIDC provider is automatically installed.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;


&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;eksctl utils associate-iam-oidc-provider --cluster loki --approve&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;create-s3-buckets&#34;&gt;Create S3 buckets&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-warning&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Warning&lt;/p&gt;&lt;p&gt;&lt;strong&gt;DO NOT&lt;/strong&gt; use the default bucket names;  &lt;code&gt;chunk&lt;/code&gt;, &lt;code&gt;ruler&lt;/code&gt; and &lt;code&gt;admin&lt;/code&gt;. Choose a &lt;strong&gt;unique&lt;/strong&gt; name for each bucket. For more information see the following &lt;a href=&#34;/blog/2024/06/27/grafana-security-update-grafana-loki-and-unintended-data-write-attempts-to-amazon-s3-buckets/&#34;&gt;security update&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;Before deploying Loki, you need to create two S3 buckets; one to store logs (chunks), the second to store alert rules. You can create the bucket using the AWS Management Console or the AWS CLI. The bucket name must be globally unique.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;GEL customers will require a third bucket to store the admin data. This bucket is not required for OSS users.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;


&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;aws s3api create-bucket --bucket  &amp;lt;YOUR CHUNK BUCKET NAME e.g. `loki-aws-dev-chunks`&amp;gt; --region &amp;lt;S3 region your account is on, e.g. `eu-west-2`&amp;gt; --create-bucket-configuration LocationConstraint=&amp;lt;S3 region your account is on, e.g. `eu-west-2`&amp;gt; \
aws s3api create-bucket --bucket  &amp;lt;YOUR RULER BUCKET NAME e.g. `loki-aws-dev-ruler`&amp;gt; --region &amp;lt;S3 REGION your account is on, e.g. `eu-west-2`&amp;gt; --create-bucket-configuration LocationConstraint=&amp;lt;S3 REGION your account is on, e.g. `eu-west-2`&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Make sure to replace the &lt;code&gt;region&lt;/code&gt; and &lt;code&gt;bucket&lt;/code&gt; name with your desired values. We will revisit the bucket policy later in this guide.&lt;/p&gt;
&lt;h2 id=&#34;defining-iam-roles-and-policies&#34;&gt;Defining IAM roles and policies&lt;/h2&gt;
&lt;p&gt;The recommended method for connecting Loki to AWS S3 is to use an IAM role. This method is more secure than using access keys and secret keys which are directly stored in the Loki configuration. The role and policy can be created using the AWS CLI or the AWS Management Console. The below steps show how to create the role and policy using the AWS CLI.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a new directory and navigate to it. Make sure to create the files in this directory. All commands in this guide assume you are in this directory.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;code&gt;loki-s3-policy.json&lt;/code&gt; file with the following content:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JSON&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-json&#34;&gt;{
    &amp;#34;Version&amp;#34;: &amp;#34;2012-10-17&amp;#34;,
    &amp;#34;Statement&amp;#34;: [
        {
            &amp;#34;Sid&amp;#34;: &amp;#34;LokiStorage&amp;#34;,
            &amp;#34;Effect&amp;#34;: &amp;#34;Allow&amp;#34;,
            &amp;#34;Action&amp;#34;: [
                &amp;#34;s3:ListBucket&amp;#34;,
                &amp;#34;s3:PutObject&amp;#34;,
                &amp;#34;s3:GetObject&amp;#34;,
                &amp;#34;s3:DeleteObject&amp;#34;
            ],
            &amp;#34;Resource&amp;#34;: [
                &amp;#34;arn:aws:s3:::&amp;lt; CHUNK BUCKET NAME &amp;gt;&amp;#34;,
                &amp;#34;arn:aws:s3:::&amp;lt; CHUNK BUCKET NAME &amp;gt;/*&amp;#34;,
                &amp;#34;arn:aws:s3:::&amp;lt; RULER BUCKET NAME &amp;gt;&amp;#34;,
                &amp;#34;arn:aws:s3:::&amp;lt; RULER BUCKET NAME &amp;gt;/*&amp;#34;
            ]
        }
    ]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Make sure to replace the placeholders with the names of the buckets you created earlier.&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create the IAM policy using the AWS CLI:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;aws iam create-policy --policy-name LokiS3AccessPolicy --policy-document file://loki-s3-policy.json&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a trust policy document named &lt;code&gt;trust-policy.json&lt;/code&gt; with the following content:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JSON&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-json&#34;&gt;{
    &amp;#34;Version&amp;#34;: &amp;#34;2012-10-17&amp;#34;,
    &amp;#34;Statement&amp;#34;: [
        {
            &amp;#34;Effect&amp;#34;: &amp;#34;Allow&amp;#34;,
            &amp;#34;Principal&amp;#34;: {
                &amp;#34;Federated&amp;#34;: &amp;#34;arn:aws:iam::&amp;lt; ACCOUNT ID &amp;gt;:oidc-provider/oidc.eks.&amp;lt;INSERT REGION&amp;gt;.amazonaws.com/id/&amp;lt; OIDC ID &amp;gt;&amp;#34;
            },
            &amp;#34;Action&amp;#34;: &amp;#34;sts:AssumeRoleWithWebIdentity&amp;#34;,
            &amp;#34;Condition&amp;#34;: {
                &amp;#34;StringEquals&amp;#34;: {
                    &amp;#34;oidc.eks.&amp;lt;INSERT REGION&amp;gt;.amazonaws.com/id/&amp;lt; OIDC ID &amp;gt;:sub&amp;#34;: &amp;#34;system:serviceaccount:loki:loki&amp;#34;,
                    &amp;#34;oidc.eks.&amp;lt;INSERT REGION&amp;gt;.amazonaws.com/id/&amp;lt; OIDC ID &amp;gt;:aud&amp;#34;: &amp;#34;sts.amazonaws.com&amp;#34;
                }
            }
        }
    ]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Make sure to replace the placeholders with your AWS account ID, region, and the OIDC ID (you can find this in the EKS cluster configuration).&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create the IAM role using the AWS CLI:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;aws iam create-role --role-name LokiServiceAccountRole --assume-role-policy-document file://trust-policy.json&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Attach the policy to the role:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;aws iam attach-role-policy --role-name LokiServiceAccountRole --policy-arn arn:aws:iam::&amp;lt;Account ID&amp;gt;:policy/LokiS3AccessPolicy&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Make sure to replace the placeholder with your AWS account ID.&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;deploying-the-helm-chart&#34;&gt;Deploying the Helm chart&lt;/h2&gt;
&lt;p&gt;Before we can deploy the Loki Helm chart, we need to add the Grafana Community chart repository to Helm. This repository contains the Loki Helm chart.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the Grafana Community chart repository to Helm:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm repo add grafana-community https://grafana-community.github.io/helm-charts&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the chart repository:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm repo update&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a new namespace for Loki:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create namespace loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;loki-basic-authentication&#34;&gt;Loki Basic Authentication&lt;/h3&gt;
&lt;p&gt;Loki by default does not come with any authentication. Since we will be deploying Loki to AWS and exposing the gateway to the internet, we recommend adding at least basic authentication. In this guide we will give Loki a username and password:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;To start we will need create a &lt;code&gt;.htpasswd&lt;/code&gt; file with the username and password. You can use the &lt;code&gt;htpasswd&lt;/code&gt; command to create the file:&lt;/p&gt;


&lt;div class=&#34;admonition admonition-tip&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Tip&lt;/p&gt;&lt;p&gt;If you don&amp;rsquo;t have the &lt;code&gt;htpasswd&lt;/code&gt; command installed, you can install it using &lt;code&gt;brew&lt;/code&gt; or &lt;code&gt;apt-get&lt;/code&gt; or &lt;code&gt;yum&lt;/code&gt; depending on your OS.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;


&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;htpasswd -c .htpasswd &amp;lt;username&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will create a file called &lt;code&gt;auth&lt;/code&gt; with the username &lt;code&gt;loki&lt;/code&gt;. You will be prompted to enter a password.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a Kubernetes secret with the &lt;code&gt;.htpasswd&lt;/code&gt; file:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create secret generic loki-basic-auth --from-file=.htpasswd -n loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will create a secret called &lt;code&gt;loki-basic-auth&lt;/code&gt; in the &lt;code&gt;loki&lt;/code&gt; namespace. We will reference this secret in the Loki Helm chart configuration.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;code&gt;canary-basic-auth&lt;/code&gt; secret for the canary:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create secret generic canary-basic-auth \
  --from-literal=username=&amp;lt;USERNAME&amp;gt; \
  --from-literal=password=&amp;lt;PASSWORD&amp;gt; \
  -n loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We create a literal secret with the username and password for Loki canary to authenticate with the Loki gateway.
&lt;strong&gt;Make sure to replace the placeholders with your desired username and password.&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;loki-helm-chart-configuration&#34;&gt;Loki Helm chart configuration&lt;/h3&gt;
&lt;p&gt;Create a &lt;code&gt;values.yaml&lt;/code&gt; file choosing the configuration options that best suit your requirements. Below there is an example of &lt;code&gt;values.yaml&lt;/code&gt; files for the Loki Helm chart in 
    &lt;a href=&#34;/docs/loki/v3.7.x/get-started/deployment-modes/#microservices-mode&#34;&gt;microservices&lt;/a&gt; mode.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;loki:
  schemaConfig:
    configs:
      - from: &amp;#34;2024-04-01&amp;#34;
        store: tsdb
        object_store: s3
        schema: v13
        index:
          prefix: loki_index_
          period: 24h
  storage_config:
    aws:
      region: &amp;lt;S3 BUCKET REGION&amp;gt; # for example, eu-west-2  
      bucketnames: &amp;lt;CHUNK BUCKET NAME&amp;gt; # Your actual S3 bucket name, for example, loki-aws-dev-chunks
      s3forcepathstyle: false
  ingester:
    chunk_encoding: snappy
  pattern_ingester:
    enabled: true
  limits_config:
    allow_structured_metadata: true
    volume_enabled: true
    retention_period: 672h # 28 days retention
  compactor:
    retention_enabled: true
    delete_request_store: s3
  ruler:
    enable_api: true
    storage:
      type: s3
      s3:
        region: &amp;lt;S3 BUCKET REGION&amp;gt; # for example, eu-west-2
        bucketnames: &amp;lt;RULER BUCKET NAME&amp;gt; # Your actual S3 bucket name, for example, loki-aws-dev-ruler
        s3forcepathstyle: false
      alertmanager_url: http://prom:9093 # The URL of the Alertmanager to send alerts (Prometheus, Mimir, etc.)

  querier:
    max_concurrent: 4

  storage:
    type: s3
    bucketNames:
      chunks: &amp;#34;&amp;lt;CHUNK BUCKET NAME&amp;gt;&amp;#34; # Your actual S3 bucket name (loki-aws-dev-chunks)
      ruler: &amp;#34;&amp;lt;RULER BUCKET NAME&amp;gt;&amp;#34; # Your actual S3 bucket name (loki-aws-dev-ruler)
      # admin: &amp;#34;&amp;lt;Insert s3 bucket name&amp;gt;&amp;#34; # Your actual S3 bucket name (loki-aws-dev-admin) - GEL customers only
    s3:
      region: &amp;lt;S3 BUCKET REGION&amp;gt; # eu-west-2
      #insecure: false
      # s3forcepathstyle: false

serviceAccount:
  create: true
  annotations:
    &amp;#34;eks.amazonaws.com/role-arn&amp;#34;: &amp;#34;arn:aws:iam::&amp;lt;Account ID&amp;gt;:role/LokiServiceAccountRole&amp;#34; # The service role you created

deploymentMode: Distributed

ingester:
  replicas: 3
  zoneAwareReplication:
    enabled: false

querier:
  replicas: 3
  maxUnavailable: 2

queryFrontend:
  replicas: 2
  maxUnavailable: 1

queryScheduler:
  replicas: 2

distributor:
  replicas: 3
  maxUnavailable: 2
compactor:
  replicas: 1

indexGateway:
  replicas: 2
  maxUnavailable: 1

ruler:
  replicas: 1
  maxUnavailable: 1


# This exposes the Loki gateway so it can be written to and queried externaly
gateway:
  service:
    type: LoadBalancer
  basicAuth:
    enabled: true
    existingSecret: loki-basic-auth

# Since we are using basic auth, we need to pass the username and password to the canary
lokiCanary:
  extraArgs:
    - -pass=$(LOKI_PASS)
    - -user=$(LOKI_USER)
  extraEnv:
    - name: LOKI_PASS
      valueFrom:
        secretKeyRef:
          name: canary-basic-auth
          key: password
    - name: LOKI_USER
      valueFrom:
        secretKeyRef:
          name: canary-basic-auth
          key: username

# Enable minio for storage
minio:
  enabled: false

backend:
  replicas: 0
read:
  replicas: 0
write:
  replicas: 0

singleBinary:
  replicas: 0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&#34;admonition admonition-caution&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Caution&lt;/p&gt;&lt;p&gt;Make sure to replace the placeholders with your actual values.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;It is critical to define a valid &lt;code&gt;values.yaml&lt;/code&gt; file for the Loki deployment. To remove the risk of misconfiguration, let&amp;rsquo;s break down the configuration options to keep in mind when deploying to AWS:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Loki Config vs. Values Config:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;values.yaml&lt;/code&gt; file contains a section called &lt;code&gt;loki&lt;/code&gt;, which contains a direct representation of the Loki configuration file.&lt;/li&gt;
&lt;li&gt;This section defines the Loki configuration, including the schema, storage, and querier configuration.&lt;/li&gt;
&lt;li&gt;The key configuration to focus on for chunks is the &lt;code&gt;storage_config&lt;/code&gt; section, where you define the S3 bucket region and name. This tells Loki where to store the chunks.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;ruler&lt;/code&gt; section defines the configuration for the ruler, including the S3 bucket region and name. This tells Loki where to store the alert and recording rules.&lt;/li&gt;
&lt;li&gt;For the full Loki configuration, refer to the 
    &lt;a href=&#34;/docs/loki/v3.7.x/configure/&#34;&gt;Loki Configuration&lt;/a&gt; documentation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Storage:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Defines where the Helm chart stores data.&lt;/li&gt;
&lt;li&gt;Set the type to &lt;code&gt;s3&lt;/code&gt; since we are using Amazon S3.&lt;/li&gt;
&lt;li&gt;Configure the bucket names for the chunks and ruler to match the buckets created earlier.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;s3&lt;/code&gt; section specifies the region of the bucket.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Service Account:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;serviceAccount&lt;/code&gt; section is used to define the IAM role for the Loki service account.&lt;/li&gt;
&lt;li&gt;This is where the IAM role created earlier is linked.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Zone-Aware Replication:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Helm chart enables zone-aware ingester replication by default, which creates three ingester StatefulSets (zone-a, zone-b, zone-c) for faster rollouts.&lt;/li&gt;
&lt;li&gt;In this guide, zone-aware replication is explicitly disabled (&lt;code&gt;ingester.zoneAwareReplication.enabled: false&lt;/code&gt;) for simplicity. For production deployments, consider enabling it to improve rollout resilience.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Gateway:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Defines how the Loki gateway will be exposed.&lt;/li&gt;
&lt;li&gt;We are using a &lt;code&gt;LoadBalancer&lt;/code&gt; service type in this configuration.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;deploy-loki&#34;&gt;Deploy Loki&lt;/h3&gt;
&lt;p&gt;Now that you have created the &lt;code&gt;values.yaml&lt;/code&gt; file, you can deploy Loki using the Helm chart.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Deploy using the newly created &lt;code&gt;values.yaml&lt;/code&gt; file:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm install --values values.yaml loki grafana-community/loki -n loki --create-namespace&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;It is important to create a namespace called &lt;code&gt;loki&lt;/code&gt; as our trust policy is set to allow the IAM role to be used by the &lt;code&gt;loki&lt;/code&gt; service account in the &lt;code&gt;loki&lt;/code&gt; namespace. This is configurable but make sure to update your service account.&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify the deployment:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl get pods -n loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You should see the Loki pods running.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;console&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-console&#34;&gt;NAME                                    READY   STATUS    RESTARTS   AGE
loki-canary-crqpg                       1/1     Running   0          10m
loki-canary-hm26p                       1/1     Running   0          10m
loki-canary-v9wv9                       1/1     Running   0          10m
loki-chunks-cache-0                     2/2     Running   0          10m
loki-compactor-0                        1/1     Running   0          10m
loki-distributor-78ccdcc9b4-9wlhl       1/1     Running   0          10m
loki-distributor-78ccdcc9b4-km6j2       1/1     Running   0          10m
loki-distributor-78ccdcc9b4-ptwrb       1/1     Running   0          10m
loki-gateway-5f97f78755-hm6mx           1/1     Running   0          10m
loki-index-gateway-0                    1/1     Running   0          10m
loki-index-gateway-1                    1/1     Running   0          10m
loki-ingester-zone-a-0                  1/1     Running   0          10m
loki-ingester-zone-b-0                  1/1     Running   0          10m
loki-ingester-zone-c-0                  1/1     Running   0          10m
loki-querier-89d4ff448-4vr9b            1/1     Running   0          10m
loki-querier-89d4ff448-7nvrf            1/1     Running   0          10m
loki-querier-89d4ff448-q89kh            1/1     Running   0          10m
loki-query-frontend-678899db5-n5wc4     1/1     Running   0          10m
loki-query-frontend-678899db5-tf69b     1/1     Running   0          10m
loki-query-scheduler-7d666bf759-9xqb5   1/1     Running   0          10m
loki-query-scheduler-7d666bf759-kpb5q   1/1     Running   0          10m
loki-results-cache-0                    2/2     Running   0          10m
loki-ruler-0                            1/1     Running   0          10m&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;find-the-loki-gateway-service&#34;&gt;Find the Loki Gateway Service&lt;/h3&gt;
&lt;p&gt;The Loki Gateway service is a LoadBalancer service that exposes the Loki gateway to the internet. This is where you will write logs to and query logs from. By default NGINX is used as the gateway.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-caution&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Caution&lt;/p&gt;&lt;p&gt;The Loki Gateway service is exposed to the internet. We provide basic authentication using a username and password in this tutorial. Refer to the 
    &lt;a href=&#34;/docs/loki/v3.7.x/operations/authentication/&#34;&gt;Authentication&lt;/a&gt; documentation for more information.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;To find the Loki Gateway service, run the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl get svc -n loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You should see the Loki Gateway service with an external IP address. This is the address you will use to write to and query Loki.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;console&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-console&#34;&gt;  NAME                             TYPE           CLUSTER-IP       EXTERNAL-IP                                                               PORT(S)              AGE
loki-gateway                     LoadBalancer   10.100.201.74    12345678975675456-1433434453245433545656563.eu-west-2.elb.amazonaws.com   80:30707/TCP         46m&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Congratulations! You have successfully deployed Loki on AWS using the Helm chart. Before we finish, let&amp;rsquo;s test the deployment.&lt;/p&gt;
&lt;h2 id=&#34;testing-your-loki-deployment&#34;&gt;Testing Your Loki Deployment&lt;/h2&gt;
&lt;p&gt;k6 is one of the fastest ways to test your Loki deployment. This will allow you to both write and query logs to Loki. To get started with k6, follow the steps below:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install k6 with the Loki extension on your local machine. Refer to 
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/k6/&#34;&gt;Installing k6 and the xk6-loki extension&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;code&gt;aws-test.js&lt;/code&gt; file with the following content:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt; import {sleep, check} from &amp;#39;k6&amp;#39;;
 import loki from &amp;#39;k6/x/loki&amp;#39;;

 /**
 * URL used for push and query requests
 * Path is automatically appended by the client
 * @constant {string}
 */

 const username = &amp;#39;&amp;lt;USERNAME&amp;gt;&amp;#39;;
 const password = &amp;#39;&amp;lt;PASSWORD&amp;gt;&amp;#39;;
 const external_ip = &amp;#39;&amp;lt;EXTERNAL-IP&amp;gt;&amp;#39;;

 const credentials = `${username}:${password}`;

 const BASE_URL = `http://${credentials}@${external_ip}`;

 /**
 * Helper constant for byte values
 * @constant {number}
 */
 const KB = 1024;

 /**
 * Helper constant for byte values
 * @constant {number}
 */
 const MB = KB * KB;

 /**
 * Instantiate config and Loki client
 */

 const conf = new loki.Config(BASE_URL);
 const client = new loki.Client(conf);

 /**
 * Define test scenario
 */
 export const options = {
   vus: 10,
   iterations: 10,
 };

 export default () =&amp;gt; {
   // Push request with 10 streams and uncompressed logs between 800KB and 2MB
   var res = client.pushParameterized(10, 800 * KB, 2 * MB);
   // Check for successful write
   check(res, { &amp;#39;successful write&amp;#39;: (res) =&amp;gt; res.status == 204 });

   // Pick a random log format from label pool
   let format = randomChoice(conf.labels[&amp;#34;format&amp;#34;]);

   // Execute instant query with limit 1
   res = client.instantQuery(`count_over_time({format=&amp;#34;${format}&amp;#34;}[1m])`, 1)
   // Check for successful read
   check(res, { &amp;#39;successful instant query&amp;#39;: (res) =&amp;gt; res.status == 200 });

   // Execute range query over last 5m and limit 1000
   res = client.rangeQuery(`{format=&amp;#34;${format}&amp;#34;}`, &amp;#34;5m&amp;#34;, 1000)
   // Check for successful read
   check(res, { &amp;#39;successful range query&amp;#39;: (res) =&amp;gt; res.status == 200 });

   // Wait before next iteration
   sleep(1);
 }

 /**
 * Helper function to get random item from array
 */
 function randomChoice(items) {
   return items[Math.floor(Math.random() * items.length)];
 }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Replace &lt;code&gt;&amp;lt;EXTERNAL-IP&amp;gt;&lt;/code&gt; with the external IP address of the Loki Gateway service.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This script will write logs to Loki and query logs from Loki. It will write logs in a random format between 800KB and 2MB and query logs in a random format over the last 5 minutes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the test:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;./k6 run aws-test.js&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will run the test and output the results. You should see the test writing logs to Loki and querying logs from Loki.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now that you have successfully deployed Loki in microservices mode on AWS, you may wish to explore the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/&#34;&gt;Sending data to Loki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/loki/v3.7.x/query/&#34;&gt;Querying Loki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/loki/v3.7.x/operations/&#34;&gt;Manage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="deploy-the-loki-helm-chart-on-aws">Deploy the Loki Helm chart on AWS&lt;/h1>
&lt;p>This guide shows how to deploy a minimally viable Loki in &lt;strong>microservice&lt;/strong> mode on AWS using the Helm chart. To run through this guide, we expect you to have the necessary tools and permissions to deploy resources on AWS, such as:&lt;/p></description></item><item><title>Deploy the Loki Helm chart on Azure</title><link>https://grafana.com/docs/loki/v3.7.x/setup/install/helm/deployment-guides/azure/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.x/setup/install/helm/deployment-guides/azure/</guid><content><![CDATA[&lt;h1 id=&#34;deploy-the-loki-helm-chart-on-azure&#34;&gt;Deploy the Loki Helm chart on Azure&lt;/h1&gt;
&lt;p&gt;This guide shows how to deploy a minimally viable Loki in &lt;strong&gt;microservice&lt;/strong&gt; mode on Azure using the Helm chart. In order to successfully complete this guide, you must have the necessary tools and permissions to deploy resources on Azure, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Full access to AKS (Azure Kubernetes Service)&lt;/li&gt;
&lt;li&gt;Full access to Azure Blob Storage&lt;/li&gt;
&lt;li&gt;Sufficient permissions to create federated credentials and roles in Azure AD (Active Directory)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are four primary ways to authenticate Loki with Azure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hard coding a connection string - this is the simplest method but is not recommended for production environments.&lt;/li&gt;
&lt;li&gt;Service principal&lt;/li&gt;
&lt;li&gt;Managed identity&lt;/li&gt;
&lt;li&gt;Federated token&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this guide, we will use the federated token method to deploy Loki on Azure. This method is more secure than hard coding a connection string and is more suitable for production environments.&lt;/p&gt;
&lt;h2 id=&#34;considerations&#34;&gt;Considerations&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-caution&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Caution&lt;/p&gt;&lt;p&gt;This guide was accurate at the time it was last updated on &lt;strong&gt;6th of February, 2026&lt;/strong&gt;.  As cloud providers frequently update their services and offerings, as a best practice, you should refer to the &lt;a href=&#34;https://learn.microsoft.com/en-us/azure/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Azure documentation&lt;/a&gt; before creating your storage account and assigning roles.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;AD Role:&lt;/strong&gt; In this tutorial we will create a role in Azure Active Directory (Azure AD) to allow Loki to read and write from Azure Blob Storage. This role will be assigned to the Loki service account. You may want to adjust the permissions based on your requirements.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Authentication:&lt;/strong&gt; Grafana Loki comes with a basic authentication layer. The Loki gateway (NGINX) is exposed to the internet using basic authentication in this example. NGINX can also be replaced with other open-source reverse proxies. Refer to 
    &lt;a href=&#34;/docs/loki/v3.7.x/operations/authentication/&#34;&gt;Authentication&lt;/a&gt; for more information.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Retention:&lt;/strong&gt; The retention period is set to 28 days in the &lt;code&gt;values.yaml&lt;/code&gt; file. You may wish to adjust this based on your requirements.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Costs:&lt;/strong&gt; Running Loki on Azure will incur costs. Make sure to monitor your usage and costs to avoid any unexpected bills. In this guide we have used a simple AKS cluster with 3 nodes and &lt;code&gt;Standard_E2ds_v5&lt;/code&gt; instances. You may wish to adjust the instance types and number of nodes based on your workload.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Helm 3 or above. Refer to &lt;a href=&#34;https://helm.sh/docs/intro/install/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Installing Helm&lt;/a&gt;. This should be installed on your local machine.&lt;/li&gt;
&lt;li&gt;Kubectl installed on your local machine. Refer to &lt;a href=&#34;https://kubernetes.io/docs/tasks/tools/install-kubectl/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Install and Set Up kubectl&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Azure CLI installed on your local machine. Refer to &lt;a href=&#34;https://learn.microsoft.com/en-us/cli/azure/install-azure-cli&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Installing the Azure CLI&lt;/a&gt;. This is a requirement for following this guide as all resources will be created using the Azure CLI.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;aks-minimum-requirements&#34;&gt;AKS minimum requirements&lt;/h3&gt;
&lt;p&gt;Before creating an AKS cluster in Azure you need to create a resource group. You can create a resource group using the Azure CLI:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;az group create --name &amp;lt;INSERT-NAME&amp;gt; -location &amp;lt;INSERT-AZURE-REGION&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&#34;admonition admonition-caution&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Caution&lt;/p&gt;&lt;p&gt;These AKS requirements are the minimum specification needed to deploy Loki using this guide. You may wish to adjust the instance types based on your Azure environment and workload. &lt;strong&gt;If you choose to do so, we cannot guarantee that this sample configuration will still meet your needs.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this guide, we deploy Loki using &lt;code&gt;Standard_E2ds_v5&lt;/code&gt; instances. This is to make sure we remain within the free tier limits for Azure. Which allows us to deploy up to 10 vCPUs within a region. We recommend for large production workloads to scale these nodes up to &lt;code&gt;Standard_D4_v5&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;The minimum requirements for deploying Loki on AKS are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes version &lt;code&gt;1.30&lt;/code&gt; or above.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;3&lt;/code&gt; nodes for the AKS cluster.&lt;/li&gt;
&lt;li&gt;Instance type depends on your workload. A good starting point for a production cluster in the free tier is &lt;code&gt;Standard_E2ds_v5&lt;/code&gt; instances and for large production workloads &lt;code&gt;Standard_D4_v5&lt;/code&gt; instances.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is how to create an AKS cluster with the minimum requirements:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;az aks create \
  --resource-group &amp;lt;MY_RESOURCE_GROUP_NAME&amp;gt; \
  --name &amp;lt;MY_AKS_CLUSTER_NAME&amp;gt; \
  --node-count 3 \
  --node-vm-size Standard_E2ds_v5 \
  --generate-ssh-keys \
  --enable-workload-identity \
  --enable-oidc-issuer&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note in the above command we have enabled workload identity and OIDC issuer. This is required for the Loki service account to authenticate with Azure AD. If you have already created an AKS cluster, you can enable these features using the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;az aks update \
  --resource-group &amp;lt;MY_RESOURCE_GROUP_NAME&amp;gt; \
  --name &amp;lt;MY_AKS_CLUSTER_NAME&amp;gt; \
  --enable-workload-identity \
  --enable-oidc-issuer&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The Azure CLI also lets you bind the AKS cluster to kubectl. You can do this by running the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;az aks get-credentials --resource-group &amp;lt;MY_RESOURCE_GROUP_NAME&amp;gt; --name &amp;lt;MY_AKS_CLUSTER_NAME&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;configuring-azure-blob-storage&#34;&gt;Configuring Azure Blob Storage&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-tip&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Tip&lt;/p&gt;&lt;p&gt;Consider using unique bucket names rather than:  &lt;code&gt;chunk&lt;/code&gt;, &lt;code&gt;ruler&lt;/code&gt;, and &lt;code&gt;admin&lt;/code&gt;. Although Azure Blog Storage is not directly affected by this &lt;a href=&#34;/blog/2024/06/27/grafana-security-update-grafana-loki-and-unintended-data-write-attempts-to-amazon-s3-buckets/&#34;&gt;security update&lt;/a&gt; it is a best practice to use unique container names for buckets.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;Before deploying Loki, you need to create two Azure storage containers; one to store logs (chunks), the second to store alert rules. You can create the containers using the Azure CLI. Containers must exist inside a storage account.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;GEL customers will require a third container to store the admin data. This container is not required for OSS users.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a storage account:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;az storage account create \
--name &amp;lt;NAME&amp;gt; \
--location &amp;lt;REGION&amp;gt; \
--sku Standard_ZRS \
--encryption-services blob \
--resource-group &amp;lt;MY_RESOURCE_GROUP_NAME&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the placeholders with your desired values.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create the containers for chunks and ruler:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;az storage container create --account-name &amp;lt;STORAGE-ACCOUNT-NAME&amp;gt; --name &amp;lt;CHUNK-BUCKET-NAME&amp;gt; --auth-mode login &amp;amp;&amp;amp; \
az storage container create --account-name &amp;lt;STORAGE-ACCOUNT-NAME&amp;gt; --name &amp;lt;RULER-BUCKET-NAME&amp;gt; --auth-mode login&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Make sure &lt;code&gt;--account-name&lt;/code&gt; matches the account you just created&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With the storage account and containers created, you can now proceed to creating the Azure AD role and federated credentials.&lt;/p&gt;
&lt;h2 id=&#34;creating-the-azure-ad-role-and-federated-credentials&#34;&gt;Creating the Azure AD role and federated credentials&lt;/h2&gt;
&lt;p&gt;The recommended way to authenticate Loki with Azure Blob Storage is to use federated credentials. This method is more secure than hard coding a connection string directly into the Loki configuration. In this next section, we will create an Azure AD role and federated credentials for Loki to allow it to read and write from Azure Blob Storage:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Locate the OpenID Connect (OIDC)  issuer URL:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;az aks show \
--resource-group &amp;lt;MY_RESOURCE_GROUP_NAME&amp;gt; \
--name &amp;lt;MY_AKS_CLUSTER_NAME&amp;gt; \
--query &amp;#34;oidcIssuerProfile.issuerUrl&amp;#34; \
-o tsv&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This command will return the OIDC issuer URL. You will need this URL to create the federated credentials.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Generate a &lt;code&gt;credentials.json&lt;/code&gt; file with the following content:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JSON&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-json&#34;&gt;{
    &amp;#34;name&amp;#34;: &amp;#34;LokiFederatedIdentity&amp;#34;,
    &amp;#34;issuer&amp;#34;: &amp;#34;&amp;lt;OIDC-ISSUER-URL&amp;gt;&amp;#34;,
    &amp;#34;subject&amp;#34;: &amp;#34;system:serviceaccount:loki:loki&amp;#34;,
    &amp;#34;description&amp;#34;: &amp;#34;Federated identity for Loki accessing Azure resources&amp;#34;,
    &amp;#34;audiences&amp;#34;: [
      &amp;#34;api://AzureADTokenExchange&amp;#34;
    ]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;lt;OIDC-ISSUER-URL&amp;gt;&lt;/code&gt; with the OIDC issuer URL you found in the previous step.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make sure you to save the &lt;code&gt;credentials.json&lt;/code&gt; file before continuing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Next generate an Azure directory &lt;code&gt;app&lt;/code&gt;. We will use this to assign our federated credentials to:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt; az ad app create \
 --display-name loki \
 --query appId \
 -o tsv&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will return the app ID. Save this for later use. If you need to find the app ID later you can run the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;az ad app list --display-name loki --query &amp;#34;[].appId&amp;#34; -o tsv&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The app requires a service principal to authenticate with Azure AD. Create a service principal for the app:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;az ad sp create --id &amp;lt;APP-ID&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;lt;APP-ID&amp;gt;&lt;/code&gt; with the app ID you generated in the previous step.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Next assign the federated credentials to the app:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;az ad app federated-credential create \
  --id &amp;lt;APP-ID&amp;gt; \
  --parameters credentials.json &lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;lt;APP-ID&amp;gt;&lt;/code&gt; with the app ID you generated in the previous step.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lastly add a role assignment to the app:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;az role assignment create \
  --role &amp;#34;Storage Blob Data Contributor&amp;#34; \
  --assignee &amp;lt;APP-ID&amp;gt; \
  --scope /subscriptions/&amp;lt;SUBSCRIPTION-ID&amp;gt;/resourceGroups/&amp;lt;RESOURCE-GROUP&amp;gt;/providers/Microsoft.Storage/storageAccounts/&amp;lt;STORAGE-ACCOUNT-NAME&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the placeholders with your actual values.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now that you have created the Azure AD role and federated credentials, you can proceed to deploying Loki using the Helm chart.&lt;/p&gt;
&lt;h2 id=&#34;deploying-the-helm-chart&#34;&gt;Deploying the Helm chart&lt;/h2&gt;
&lt;p&gt;The following steps require the use of &lt;code&gt;helm&lt;/code&gt; and &lt;code&gt;kubectl&lt;/code&gt;. Make sure you have run the &lt;code&gt;az&lt;/code&gt; command to bind your AKS cluster to &lt;code&gt;kubectl&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;az aks get-credentials --resource-group &amp;lt;MY_RESOURCE_GROUP_NAME&amp;gt; --name &amp;lt;MY_AKS_CLUSTER_NAME&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Before we can deploy the Loki Helm chart, we need to add the Grafana Community chart repository to Helm. This repository contains the Loki Helm chart.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the Grafana Community chart repository to Helm:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm repo add grafana-community https://grafana-community.github.io/helm-charts&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the chart repository:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm repo update&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a new namespace for Loki:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create namespace loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;loki-basic-authentication&#34;&gt;Loki basic authentication&lt;/h3&gt;
&lt;p&gt;Loki by default does not come with any authentication. Since we will be deploying Loki to Azure and exposing the gateway to the internet, we recommend adding at least basic authentication. In this guide we will give Loki a username and password:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;To start we will need create a &lt;code&gt;.htpasswd&lt;/code&gt; file with the username and password. You can use the &lt;code&gt;htpasswd&lt;/code&gt; command to create the file:&lt;/p&gt;


&lt;div class=&#34;admonition admonition-tip&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Tip&lt;/p&gt;&lt;p&gt;If you don&amp;rsquo;t have the &lt;code&gt;htpasswd&lt;/code&gt; command installed, you can install it using &lt;code&gt;brew&lt;/code&gt; or &lt;code&gt;apt-get&lt;/code&gt; or &lt;code&gt;yum&lt;/code&gt; depending on your OS.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;


&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;htpasswd -c .htpasswd &amp;lt;username&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will create a file called &lt;code&gt;auth&lt;/code&gt; with the username &lt;code&gt;loki&lt;/code&gt;. You will be prompted to enter a password.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a Kubernetes secret with the &lt;code&gt;.htpasswd&lt;/code&gt; file:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create secret generic loki-basic-auth --from-file=.htpasswd -n loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will create a secret called &lt;code&gt;loki-basic-auth&lt;/code&gt; in the &lt;code&gt;loki&lt;/code&gt; namespace. We will reference this secret in the Loki Helm chart configuration.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;code&gt;canary-basic-auth&lt;/code&gt; secret for the canary:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create secret generic canary-basic-auth \
  --from-literal=username=&amp;lt;USERNAME&amp;gt; \
  --from-literal=password=&amp;lt;PASSWORD&amp;gt; \
  -n loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We create a literal secret with the username and password for Loki canary to authenticate with the Loki gateway. Make sure to replace the placeholders with your desired username and password.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;loki-helm-chart-configuration&#34;&gt;Loki Helm chart configuration&lt;/h3&gt;
&lt;p&gt;Create a &lt;code&gt;values.yaml&lt;/code&gt; file choosing the configuration options that best suit your requirements. Below there is an example of &lt;code&gt;values.yaml&lt;/code&gt; files for the Loki Helm chart in 
    &lt;a href=&#34;/docs/loki/v3.7.x/get-started/deployment-modes/#microservices-mode&#34;&gt;microservices&lt;/a&gt; mode.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;loki:
  podLabels:
    &amp;#34;azure.workload.identity/use&amp;#34;: &amp;#34;true&amp;#34; # Add this label to the Loki pods to enable workload identity
  schemaConfig:
    configs:
      - from: &amp;#34;2024-04-01&amp;#34;
        store: tsdb
        object_store: azure
        schema: v13
        index:
          prefix: loki_index_
          period: 24h
  storage:
    type: azure
    bucketNames:
      chunks: &amp;#34;&amp;lt;CHUNK-CONTAINER-NAME&amp;gt;&amp;#34; # Your actual Azure Blob Storage container name (loki-azure-dev-chunks)
      ruler: &amp;#34;&amp;lt;RULER-CONTAINER-NAME&amp;gt;&amp;#34; # Your actual Azure Blob Storage container name (loki-azure-dev-ruler)
      # admin: &amp;#34;admin-loki-devrel&amp;#34; # Your actual Azure Blob Storage container name (loki-azure-dev-admin)
    azure:
      accountName: &amp;lt;INSERT-STORAGE-ACCOUNT-NAME&amp;gt;
      useFederatedToken: true # Use federated token for authentication
  ingester:
    chunk_encoding: snappy
  pattern_ingester:
    enabled: true
  limits_config:
    allow_structured_metadata: true
    volume_enabled: true
    retention_period: 672h # 28 days retention
  compactor:
    retention_enabled: true
    delete_request_store: azure
  ruler:
    enable_api: true
    alertmanager_url: http://prom:9093 # The URL of the Alertmanager to send alerts (Prometheus, Mimir, etc.)

  querier:
    max_concurrent: 4

# Define the Azure workload identity
serviceAccount:
  name: loki
  annotations:
    &amp;#34;azure.workload.identity/client-id&amp;#34;: &amp;#34;&amp;lt;APP-ID&amp;gt;&amp;#34; # The app ID of the Azure AD app

deploymentMode: Distributed

ingester:
  replicas: 3
  zoneAwareReplication:
    enabled: false

querier:
  replicas: 3
  maxUnavailable: 2

queryFrontend:
  replicas: 2
  maxUnavailable: 1

queryScheduler:
  replicas: 2

distributor:
  replicas: 3
  maxUnavailable: 2

compactor:
  replicas: 1

indexGateway:
  replicas: 2
  maxUnavailable: 1

ruler:
  replicas: 1
  maxUnavailable: 1


# This exposes the Loki gateway so it can be written to and queried externaly
gateway:
  service:
    type: LoadBalancer
  basicAuth: 
    enabled: true
    existingSecret: loki-basic-auth

# Since we are using basic auth, we need to pass the username and password to the canary
lokiCanary:
  extraArgs:
    - -pass=$(LOKI_PASS)
    - -user=$(LOKI_USER)
  extraEnv:
    - name: LOKI_PASS
      valueFrom:
        secretKeyRef:
          name: canary-basic-auth
          key: password
    - name: LOKI_USER
      valueFrom:
        secretKeyRef:
          name: canary-basic-auth
          key: username

# Enable minio for storage
minio:
  enabled: false

backend:
  replicas: 0
read:
  replicas: 0
write:
  replicas: 0

singleBinary:
  replicas: 0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&#34;admonition admonition-caution&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Caution&lt;/p&gt;&lt;p&gt;Make sure to replace the placeholders with your actual values.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;It is critical to define a valid &lt;code&gt;values.yaml&lt;/code&gt; file for the Loki deployment. To remove the risk of misconfiguration, let&amp;rsquo;s break down the configuration options to keep in mind when deploying to Azure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Loki Config vs. Values Config:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;values.yaml&lt;/code&gt; file contains a section called &lt;code&gt;loki&lt;/code&gt;, which contains a direct representation of the Loki configuration file.&lt;/li&gt;
&lt;li&gt;This section defines the Loki configuration, including the schema, storage, and querier configuration.&lt;/li&gt;
&lt;li&gt;The key configuration to focus on for chunks is the &lt;code&gt;storage&lt;/code&gt; section, where you define the Azure container name and storage account. This tells Loki where to store the chunks.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;ruler&lt;/code&gt; section defines the configuration for the ruler, including the Azure container name and storage account. This tells Loki where to store the alert and recording rules.&lt;/li&gt;
&lt;li&gt;For the full Loki configuration, refer to the 
    &lt;a href=&#34;/docs/loki/v3.7.x/configure/&#34;&gt;Loki Configuration&lt;/a&gt; documentation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Storage:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Defines where the Helm chart stores data.&lt;/li&gt;
&lt;li&gt;Set the type to &lt;code&gt;azure&lt;/code&gt; since we are using Azure Blob Storage.&lt;/li&gt;
&lt;li&gt;Configure the container names for the chunks and ruler to match the containers created earlier.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;azure&lt;/code&gt; section specifies the storage account name and also sets &lt;code&gt;useFederatedToken&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;. This tells Loki to use federated credentials for authentication.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Service Account:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;serviceAccount&lt;/code&gt; section is used to define the federated workload identity Loki will use to authenticate with Azure AD.&lt;/li&gt;
&lt;li&gt;We set the &lt;code&gt;azure.workload.identity/client-id&lt;/code&gt; annotation to the app ID of the Azure AD app.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Zone-Aware Replication:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Helm chart enables zone-aware ingester replication by default, which creates three ingester StatefulSets (zone-a, zone-b, zone-c) for faster rollouts.&lt;/li&gt;
&lt;li&gt;In this guide, zone-aware replication is explicitly disabled (&lt;code&gt;ingester.zoneAwareReplication.enabled: false&lt;/code&gt;) for simplicity. For production deployments, consider enabling it to improve rollout resilience.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Gateway:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Defines how the Loki gateway will be exposed.&lt;/li&gt;
&lt;li&gt;We are using a &lt;code&gt;LoadBalancer&lt;/code&gt; service type in this configuration.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;deploy-loki&#34;&gt;Deploy Loki&lt;/h3&gt;
&lt;p&gt;Now that you have created the &lt;code&gt;values.yaml&lt;/code&gt; file, you can deploy Loki using the Helm chart.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Deploy using the newly created &lt;code&gt;values.yaml&lt;/code&gt; file:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm install --values values.yaml loki grafana-community/loki -n loki --create-namespace&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;It is important to create a namespace called &lt;code&gt;loki&lt;/code&gt; as our federated credentials were generated with the  value &lt;code&gt;system:serviceaccount:loki:loki&lt;/code&gt;. This translates to the &lt;code&gt;loki&lt;/code&gt; service account in the &lt;code&gt;loki&lt;/code&gt; namespace. This is configurable but make sure to update the federated credentials file first.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify the deployment:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl get pods -n loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You should see the Loki pods running.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;console&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-console&#34;&gt;NAME                                    READY   STATUS    RESTARTS   AGE
loki-canary-crqpg                       1/1     Running   0          10m
loki-canary-hm26p                       1/1     Running   0          10m
loki-canary-v9wv9                       1/1     Running   0          10m
loki-chunks-cache-0                     2/2     Running   0          10m
loki-compactor-0                        1/1     Running   0          10m
loki-distributor-78ccdcc9b4-9wlhl       1/1     Running   0          10m
loki-distributor-78ccdcc9b4-km6j2       1/1     Running   0          10m
loki-distributor-78ccdcc9b4-ptwrb       1/1     Running   0          10m
loki-gateway-5f97f78755-hm6mx           1/1     Running   0          10m
loki-index-gateway-0                    1/1     Running   0          10m
loki-index-gateway-1                    1/1     Running   0          10m
loki-ingester-zone-a-0                  1/1     Running   0          10m
loki-ingester-zone-b-0                  1/1     Running   0          10m
loki-ingester-zone-c-0                  1/1     Running   0          10m
loki-querier-89d4ff448-4vr9b            1/1     Running   0          10m
loki-querier-89d4ff448-7nvrf            1/1     Running   0          10m
loki-querier-89d4ff448-q89kh            1/1     Running   0          10m
loki-query-frontend-678899db5-n5wc4     1/1     Running   0          10m
loki-query-frontend-678899db5-tf69b     1/1     Running   0          10m
loki-query-scheduler-7d666bf759-9xqb5   1/1     Running   0          10m
loki-query-scheduler-7d666bf759-kpb5q   1/1     Running   0          10m
loki-results-cache-0                    2/2     Running   0          10m
loki-ruler-0                            1/1     Running   0          10m&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;find-the-loki-gateway-service&#34;&gt;Find the Loki gateway service&lt;/h3&gt;
&lt;p&gt;The Loki gateway service is a load balancer service that exposes the Loki gateway to the internet. This is where you will write logs to and query logs from. By default NGINX is used as the gateway.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-caution&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Caution&lt;/p&gt;&lt;p&gt;The Loki gateway service is exposed to the internet. We provide basic authentication using a username and password in this tutorial. Refer to the 
    &lt;a href=&#34;/docs/loki/v3.7.x/operations/authentication/&#34;&gt;Authentication&lt;/a&gt; documentation for more information.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;To find the Loki gateway service, run the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl get svc -n loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You should see the Loki gateway service with an external IP address. This is the address you will use to write to and query Loki.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;console&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-console&#34;&gt;  NAME                             TYPE           CLUSTER-IP       EXTERNAL-IP    PORT(S)              AGE
loki-gateway                     LoadBalancer   10.100.201.74     134.236.21.145  80:30707/TCP         46m&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Congratulations! You have successfully deployed Loki on Azure using the Helm chart. Before we finish, let&amp;rsquo;s test the deployment.&lt;/p&gt;
&lt;h2 id=&#34;testing-your-loki-deployment&#34;&gt;Testing Your Loki Deployment&lt;/h2&gt;
&lt;p&gt;k6 is one of the fastest ways to test your Loki deployment. This will allow you to both write and query logs to Loki. To get started with k6, follow the steps below:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install k6 with the Loki extension on your local machine. Refer to 
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/k6/&#34;&gt;Installing k6 and the xk6-loki extension&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;code&gt;azure-test.js&lt;/code&gt; file with the following content:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt; import {sleep, check} from &amp;#39;k6&amp;#39;;
 import loki from &amp;#39;k6/x/loki&amp;#39;;

 /**
 * URL used for push and query requests
 * Path is automatically appended by the client
 * @constant {string}
 */

 const username = &amp;#39;&amp;lt;USERNAME&amp;gt;&amp;#39;;
 const password = &amp;#39;&amp;lt;PASSWORD&amp;gt;&amp;#39;;
 const external_ip = &amp;#39;&amp;lt;EXTERNAL-IP&amp;gt;&amp;#39;;

 const credentials = `${username}:${password}`;

 const BASE_URL = `http://${credentials}@${external_ip}`;

 /**
 * Helper constant for byte values
 * @constant {number}
 */
 const KB = 1024;

 /**
 * Helper constant for byte values
 * @constant {number}
 */
 const MB = KB * KB;

 /**
 * Instantiate config and Loki client
 */

 const conf = new loki.Config(BASE_URL);
 const client = new loki.Client(conf);

 /**
 * Define test scenario
 */
 export const options = {
   vus: 10,
   iterations: 10,
 };

 export default () =&amp;gt; {
   // Push request with 10 streams and uncompressed logs between 800KB and 2MB
   var res = client.pushParameterized(10, 800 * KB, 2 * MB);
   // Check for successful write
   check(res, { &amp;#39;successful write&amp;#39;: (res) =&amp;gt; res.status == 204 });

   // Pick a random log format from label pool
   let format = randomChoice(conf.labels[&amp;#34;format&amp;#34;]);

   // Execute instant query with limit 1
   res = client.instantQuery(`count_over_time({format=&amp;#34;${format}&amp;#34;}[1m])`, 1)
   // Check for successful read
   check(res, { &amp;#39;successful instant query&amp;#39;: (res) =&amp;gt; res.status == 200 });

   // Execute range query over last 5m and limit 1000
   res = client.rangeQuery(`{format=&amp;#34;${format}&amp;#34;}`, &amp;#34;5m&amp;#34;, 1000)
   // Check for successful read
   check(res, { &amp;#39;successful range query&amp;#39;: (res) =&amp;gt; res.status == 200 });

   // Wait before next iteration
   sleep(1);
 }

 /**
 * Helper function to get random item from array
 */
 function randomChoice(items) {
   return items[Math.floor(Math.random() * items.length)];
 }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;lt;EXTERNAL-IP&amp;gt;&lt;/code&gt; with the external IP address of the Loki Gateway service.&lt;/p&gt;
&lt;p&gt;This script will write logs to Loki and query logs from Loki. It will write logs in a random format between 800KB and 2MB and query logs in a random format over the last 5 minutes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the test:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;./k6 run azure-test.js&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will run the test and output the results. You should see the test writing logs to Loki and querying logs from Loki.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now that you have successfully deployed Loki in microservices mode on Microsoft Azure, you may wish to explore the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/&#34;&gt;Sending data to Loki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/loki/v3.7.x/query/&#34;&gt;Querying Loki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/loki/v3.7.x/operations/&#34;&gt;Manage Loki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="deploy-the-loki-helm-chart-on-azure">Deploy the Loki Helm chart on Azure&lt;/h1>
&lt;p>This guide shows how to deploy a minimally viable Loki in &lt;strong>microservice&lt;/strong> mode on Azure using the Helm chart. In order to successfully complete this guide, you must have the necessary tools and permissions to deploy resources on Azure, such as:&lt;/p></description></item><item><title>Deploy the Loki Helm chart on GCP</title><link>https://grafana.com/docs/loki/v3.7.x/setup/install/helm/deployment-guides/gcp/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.x/setup/install/helm/deployment-guides/gcp/</guid><content><![CDATA[&lt;h1 id=&#34;deploy-the-loki-helm-chart-on-gcp&#34;&gt;Deploy the Loki Helm chart on GCP&lt;/h1&gt;
&lt;p&gt;This guide shows how to deploy a minimally viable Loki in &lt;strong&gt;microservices&lt;/strong&gt; mode on Google Cloud Platform (GCP) using the Helm chart. To run through this guide, we expect you to have the necessary tools and permissions to deploy resources on GCP, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Full access to Google Kubernetes Engine (GKE)&lt;/li&gt;
&lt;li&gt;Full access to Google Cloud Storage (GCS)&lt;/li&gt;
&lt;li&gt;Sufficient permissions to create Identity Access Management (IAM) roles and policies&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are two methods for authenticating and connecting Loki to GCP GCS. We will guide you through the recommended method of granting access via an IAM role: using Workload Identity Federation.&lt;/p&gt;
&lt;h2 id=&#34;considerations&#34;&gt;Considerations&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-caution&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Caution&lt;/p&gt;&lt;p&gt;This guide was accurate at the time it was last updated on &lt;strong&gt;10th of June, 2025&lt;/strong&gt;.  As cloud providers frequently update their services and offerings, as a best practice, you should refer to the &lt;a href=&#34;https://cloud.google.com/storage/docs/introduction&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;GCP GCS documentation&lt;/a&gt; before creating your buckets and assigning roles.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;IAM Role:&lt;/strong&gt; The IAM role created in this guide is a basic role that allows Loki to read and write to the GCS bucket. You may wish to add more granular permissions based on your requirements.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Authentication:&lt;/strong&gt; Grafana Loki comes with a basic authentication layer. The Loki gateway (NGINX) is exposed to the internet using basic authentication in this example. NGINX can also be replaced with other open-source reverse proxies. Refer to 
    &lt;a href=&#34;/docs/loki/v3.7.x/operations/authentication/&#34;&gt;Authentication&lt;/a&gt; for more information.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Retention:&lt;/strong&gt; The retention period is set to 28 days in the &lt;code&gt;values.yaml&lt;/code&gt; file. You may wish to adjust this based on your requirements.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Costs:&lt;/strong&gt; Running Loki on GCP will incur costs. Make sure to monitor your usage and costs to avoid any unexpected bills. In this guide we have used a simple GKE cluster with 3 nodes (n2-standard-8 instances). You may wish to adjust the instance types and number of nodes based on your workload.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Helm 3 or above. Refer to &lt;a href=&#34;https://helm.sh/docs/intro/install/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Installing Helm&lt;/a&gt;. This should be installed on your local machine.&lt;/li&gt;
&lt;li&gt;A running Kubernetes cluster on GCP. Refer to &lt;a href=&#34;https://cloud.google.com/kubernetes-engine/docs/quickstarts/create-cluster&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Create a cluster and deploy a workload in the Google Cloud console&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Kubectl installed on your local machine. Refer to &lt;a href=&#34;https://kubernetes.io/docs/tasks/tools/install-kubectl/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Install and Set Up kubectl&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;gcloud CLI installed on your local machine. Refer to &lt;a href=&#34;https://cloud.google.com/sdk/docs/install-sdk&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Install the Google Cloud CLI&lt;/a&gt;. In this guide, we use gcloud CLI to create the GKE cluster and modify the IAM roles and policies locally.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;gke-minimum-requirements&#34;&gt;GKE Minimum Requirements&lt;/h3&gt;


&lt;div class=&#34;admonition admonition-caution&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Caution&lt;/p&gt;&lt;p&gt;These GKE requirements are the minimum specification needed to deploy Loki using this guide. You may wish to adjust plugins and instance types based on your GCP environment and workload. &lt;strong&gt;If you choose to do so, we cannot guarantee that this sample configuration will still meet your needs.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this guide, we deploy Loki using &lt;code&gt;n2-standard-8&lt;/code&gt; instances. This is a instance type that should work for most scenarios. However, you can modify the instance types and count based on your specific needs.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;The minimum requirements for deploying Loki on GKE are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes version &lt;code&gt;1.30&lt;/code&gt; or above.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;3&lt;/code&gt; nodes for the GKE cluster.&lt;/li&gt;
&lt;li&gt;Instance type depends on your workload. A good starting point for a production cluster is &lt;code&gt;n2-standard-8&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To allow kubectl to support GKE, install the gcloud kubectl auth plugin:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gcloud components install gke-gcloud-auth-plugin&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This plugin is necessary to use kubectl to authenticate with GKE. &lt;a href=&#34;https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Click here for more details on this plugin&lt;/a&gt;.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-warning&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Warning&lt;/p&gt;&lt;p&gt;Regional clusters in GKE are designed for resilience, and thus by default span three zones within the region. In the command below, &lt;code&gt;num-nodes=1&lt;/code&gt;. Note that if you set &lt;code&gt;num_nodes=3&lt;/code&gt;, you would get 9 nodes in total for the region: 3 in &lt;em&gt;each&lt;/em&gt; zone. Therefore, leave &lt;code&gt;num_nodes=1&lt;/code&gt; when you create your cluster.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;Here is an example of a command you can run using gcloud CLI to create a new cluster:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gcloud container clusters create loki-gcp \
  --location=europe-west4 \
  --num-nodes=1 \
  --machine-type=n2-standard-8 \
  --release-channel=regular \
  --workload-pool=&amp;lt;PROJECT_ID&amp;gt;.svc.id.goog \
  --enable-ip-alias \
  --no-enable-basic-auth \
  --no-issue-client-certificate&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;lt;PROJECT_ID&amp;gt;&lt;/code&gt; with the ID of the project you want to create the cluster in. This should be something like &lt;code&gt;my-project-123456&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;create-gcs-buckets&#34;&gt;Create GCS buckets&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-warning&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Warning&lt;/p&gt;&lt;p&gt;&lt;strong&gt;DO NOT&lt;/strong&gt; use the default bucket names;  &lt;code&gt;chunks&lt;/code&gt;, &lt;code&gt;ruler&lt;/code&gt; and &lt;code&gt;admin&lt;/code&gt;. Choose a &lt;strong&gt;unique&lt;/strong&gt; name for each bucket. For more information see the following &lt;a href=&#34;/blog/2024/06/27/grafana-security-update-grafana-loki-and-unintended-data-write-attempts-to-amazon-s3-buckets/&#34;&gt;security update&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;Before deploying Loki, you need to create two GCS buckets: one to store logs (chunks) and another to store alert rules (ruler). You can create the bucket using the GCP Management Console or the GCP CLI. The bucket name must be globally unique.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;GEL customers will require a third bucket to store the admin data. This bucket is not required for OSS users.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;


&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gcloud storage buckets create gs://&amp;lt;CHUNKS_BUCKET_NAME&amp;gt; gs://&amp;lt;RULER_BUCKET_NAME&amp;gt; \
  --location=&amp;lt;REGION&amp;gt; \
  --default-storage-class=STANDARD \
  --public-access-prevention \
  --uniform-bucket-level-access \
  --soft-delete-duration=7d&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Make sure to replace the &lt;code&gt;region&lt;/code&gt; and &lt;code&gt;bucket&lt;/code&gt; name with your desired values. We will revisit the bucket policy later in this guide.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example with all the variables filled in:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gcloud storage buckets create gs://loki-gcp-chunks gs://loki-gcp-ruler \
  --location=europe-west4 \
  --default-storage-class=STANDARD \
  --public-access-prevention \
  --uniform-bucket-level-access \
  --soft-delete-duration=7d&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When you run this command, you should get something like this in response:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;console&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-console&#34;&gt;Creating gs://loki-gcp-chunks/...
Creating gs://loki-gcp-ruler/...&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;defining-iam-roles-and-policies&#34;&gt;Defining IAM roles and policies&lt;/h2&gt;
&lt;p&gt;IAM determines who can access which resources on GCP and can be configured in several ways. The recommended method for allowing Loki to access GCS is to use Workload Identity Federation. This method is more secure than creating and distributing a service account key. The following steps show how to create the role and policy using the gcloud CLI.&lt;/p&gt;
&lt;h3 id=&#34;authenticating-to-the-gke-cluster&#34;&gt;Authenticating to the GKE cluster&lt;/h3&gt;
&lt;p&gt;You need to be able to run &lt;code&gt;kubectl&lt;/code&gt; commands on the cluster, so make sure you have it installed (run &lt;code&gt;gcloud components install kubectl&lt;/code&gt; if not) and then run this command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gcloud container clusters get-credentials &amp;lt;CLUSTER_NAME&amp;gt; \
  --region=&amp;lt;REGION&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Here&amp;rsquo;s an example of that command with the variables filled in:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gcloud container clusters get-credentials loki-gcp \
  --region=europe-west4&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will authenticate you via your GCP IAM identity, write the cluster&amp;rsquo;s access info to your local kubeconfig (usually &lt;code&gt;~/.kube/config&lt;/code&gt;), and then allow &lt;code&gt;kubectl&lt;/code&gt; commands to talk to the right cluster from now on.&lt;/p&gt;
&lt;p&gt;Then check that you&amp;rsquo;re connected to the GKE cluster and that you&amp;rsquo;re accessing it via &lt;code&gt;kubectl&lt;/code&gt; by running:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl config current-context&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You should get something like this in return:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gke_my-project-123456_europe-west4_loki-gcp&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;create-a-kubernetes-namespace&#34;&gt;Create a Kubernetes Namespace&lt;/h3&gt;
&lt;p&gt;Create a Kubernetes namespace where you&amp;rsquo;ll install your Loki workloads:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create namespace &amp;lt;NAMESPACE&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;lt;NAMESPACE&amp;gt;&lt;/code&gt; with the namespace where your Loki workloads will be located.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create namespace loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You should get the output:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;namespace/loki created&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;create-kubernetes-service-account-ksa&#34;&gt;Create Kubernetes Service Account (KSA)&lt;/h3&gt;
&lt;p&gt;A KSA is a cluster identity (service account, named &lt;code&gt;default&lt;/code&gt; by default) assigned to pods that allows pods to interact with each other.&lt;/p&gt;
&lt;p&gt;Create a KSA on your Kubernetes cluster:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create serviceaccount &amp;lt;KSA_NAME&amp;gt; \
  --namespace &amp;lt;NAMESPACE&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;lt;KSA_NAME&amp;gt;&lt;/code&gt; with the name of the KSA created above, and &lt;code&gt;&amp;lt;NAMESPACE&amp;gt;&lt;/code&gt; with the namespace where your Loki workloads are located.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create serviceaccount loki-gcp-ksa \
  --namespace loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You should get this in response:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;serviceaccount/loki-gcp-ksa created&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;add-iam-policy-to-buckets&#34;&gt;Add IAM Policy to Buckets&lt;/h3&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;The &lt;a href=&#34;https://cloud.google.com/storage/docs/access-control/iam-roles#storage.objectUser&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;pre-defined &lt;code&gt;roles/storage.objectUser&lt;/code&gt; role&lt;/a&gt; is sufficient for Loki to
operate. See &lt;a href=&#34;https://cloud.google.com/storage/docs/access-control/iam-permissions&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;IAM permissions for Cloud Storage&lt;/a&gt; for details about each individual
permission. You can use this predefined role or create your own with matching permissions.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;Create an IAM policy binding on the buckets using the KSA created previously and the roles of your choice. Use a separate command for each bucket, one for chunks, and another for the ruler.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gcloud storage buckets add-iam-policy-binding gs://&amp;lt;BUCKET_NAME&amp;gt; \
 --role=roles/storage.objectUser \
  --member=principal://iam.googleapis.com/projects/&amp;lt;PROJECT_NUMBER&amp;gt;/locations/global/workloadIdentityPools/&amp;lt;PROJECT_ID&amp;gt;.svc.id.goog/subject/ns/&amp;lt;NAMESPACE&amp;gt;/sa/&amp;lt;KSA_NAME&amp;gt; \
  --condition=None&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;lt;PROJECT_ID&amp;gt;&lt;/code&gt; with the GCP project ID (for example, project-name), &lt;code&gt;&amp;lt;PROJECT_NUMBER&amp;gt;&lt;/code&gt; with the project number (for example, 1234567890),
&lt;code&gt;&amp;lt;NAMESPACE&amp;gt;&lt;/code&gt; with the namespace where Loki is installed, and &lt;code&gt;&amp;lt;KSA_NAME&amp;gt;&lt;/code&gt; with the name of the KSA you created above.&lt;/p&gt;
&lt;p&gt;Then do the same thing for the other bucket.&lt;/p&gt;
&lt;p&gt;Examples:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gcloud storage buckets add-iam-policy-binding gs://loki-gcp-chunks \
  --role=roles/storage.objectUser \
  --member=principal://iam.googleapis.com/projects/12345678901/locations/global/workloadIdentityPools/my-project-123456.svc.id.goog/subject/ns/loki/sa/loki-gcp-ksa \
  --condition=None&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;gcloud storage buckets add-iam-policy-binding gs://loki-gcp-ruler \
  --role=roles/storage.objectUser \
  --member=principal://iam.googleapis.com/projects/12345678901/locations/global/workloadIdentityPools/my-project-123456.svc.id.goog/subject/ns/loki/sa/loki-gcp-ksa \
  --condition=None&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You should get something like this in response:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;bindings:
- members:
  - projectEditor:my-project-123456
  - projectOwner:my-project-123456
  role: roles/storage.legacyBucketOwner
- members:
  - projectViewer:my-project-123456
  role: roles/storage.legacyBucketReader
- members:
  - projectEditor:my-project-123456
  - projectOwner:my-project-123456
  role: roles/storage.legacyObjectOwner
- members:
  - projectViewer:my-project-123456
  role: roles/storage.legacyObjectReader
- members:
  - principal://iam.googleapis.com/projects/12345678901/locations/global/workloadIdentityPools/my-project-123456.svc.id.goog/subject/ns/loki/sa/loki-gcp-ksa
  role: roles/storage.objectUser
etag: CAI=
kind: storage#policy
resourceId: projects/_/buckets/loki-gcp-chunks
version: 1&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;deploying-the-helm-chart&#34;&gt;Deploying the Helm chart&lt;/h2&gt;
&lt;p&gt;Before we can deploy the Loki Helm chart, we need to add the Grafana Community chart repository to Helm. This repository contains the Loki Helm chart.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the Grafana Community chart repository to Helm:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm repo add grafana-community https://grafana-community.github.io/helm-charts&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the chart repository:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm repo update&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;loki-basic-authentication&#34;&gt;Loki Basic Authentication&lt;/h3&gt;
&lt;p&gt;Loki by default does not come with any authentication. Since we will be deploying Loki to GCP and exposing the gateway to the internet, we recommend adding at least basic authentication. In this guide we will give Loki a username and password:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;To start we will need create a &lt;code&gt;.htpasswd&lt;/code&gt; file with the username and password. You can use the &lt;code&gt;htpasswd&lt;/code&gt; command to create the file:&lt;/p&gt;


&lt;div class=&#34;admonition admonition-tip&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Tip&lt;/p&gt;&lt;p&gt;If you don&amp;rsquo;t have the &lt;code&gt;htpasswd&lt;/code&gt; command installed, you can install it using &lt;code&gt;brew&lt;/code&gt; or &lt;code&gt;apt-get&lt;/code&gt; or &lt;code&gt;yum&lt;/code&gt; depending on your OS.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;


&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;htpasswd -c .htpasswd &amp;lt;username&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will create a file called &lt;code&gt;auth&lt;/code&gt; with the username &lt;code&gt;loki&lt;/code&gt;. You will be prompted to enter a password.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a Kubernetes secret with the &lt;code&gt;.htpasswd&lt;/code&gt; file:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create secret generic loki-basic-auth --from-file=.htpasswd -n loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will create a secret called &lt;code&gt;loki-basic-auth&lt;/code&gt; in the &lt;code&gt;loki&lt;/code&gt; namespace. We will reference this secret in the Loki Helm chart configuration.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;code&gt;canary-basic-auth&lt;/code&gt; secret for the canary:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create secret generic canary-basic-auth \
  --from-literal=username=&amp;lt;USERNAME&amp;gt; \
  --from-literal=password=&amp;lt;PASSWORD&amp;gt; \
  -n loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We create a literal secret with the username and password for Loki canary to authenticate with the Loki gateway.
&lt;strong&gt;Make sure to replace the placeholders with your desired username and password.&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;loki-helm-chart-configuration&#34;&gt;Loki Helm chart configuration&lt;/h3&gt;
&lt;p&gt;Create a &lt;code&gt;values.yaml&lt;/code&gt; file choosing the configuration options that best suit your requirements. Below there is an example of &lt;code&gt;values.yaml&lt;/code&gt; files for the Loki Helm chart in 
    &lt;a href=&#34;/docs/loki/v3.7.x/get-started/deployment-modes/#microservices-mode&#34;&gt;microservices&lt;/a&gt; mode.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;loki:
  schemaConfig:
    configs:
      - from: &amp;#34;2024-04-01&amp;#34;
        store: tsdb
        object_store: gcs
        schema: v13
        index:
          prefix: loki_index_
          period: 24h
  storage_config:
    gcs:
      bucket_name: &amp;lt;CHUNK_BUCKET_NAME&amp;gt; # Your actual gcs bucket name, for example, loki-gcp-chunks
  ingester:
    chunk_encoding: snappy
  pattern_ingester:
    enabled: true
  limits_config:
    allow_structured_metadata: true
    volume_enabled: true
    retention_period: 672h # 28 days retention
  compactor:
    retention_enabled: true
    delete_request_store: gcs
  ruler:
    enable_api: true
    storage_config:
      type: gcs
      gcs_storage_config:
        region: &amp;lt;REGION&amp;gt; # The GCS region, for example europe-west4
        bucketnames: &amp;lt;RULER_BUCKET_NAME&amp;gt; # Your actual gcs bucket name, for example, loki-gcp-ruler
      alertmanager_url: http://prom:9093 # The URL of the Alertmanager to send alerts (Prometheus, Mimir, etc.)

  querier:
    max_concurrent: 4

  storage:
    type: gcs
    bucketNames:
      chunks: &amp;lt;CHUNK_BUCKET_NAME&amp;gt; # Your actual gcs bucket name, for example, loki-gcp-chunks
      ruler: &amp;lt;RULER_BUCKET_NAME&amp;gt; # Your actual gcs bucket name, for example, loki-gcp-ruler
      
serviceAccount:
  create: false
  name: &amp;lt;KSA_NAME&amp;gt;

deploymentMode: Distributed

ingester:
  replicas: 3
  zoneAwareReplication:
    enabled: false

querier:
  replicas: 3
  maxUnavailable: 2

queryFrontend:
  replicas: 2
  maxUnavailable: 1

queryScheduler:
  replicas: 2

distributor:
  replicas: 3
  maxUnavailable: 2
 
compactor:
  replicas: 1

indexGateway:
  replicas: 2
  maxUnavailable: 1

ruler:
  replicas: 1
  maxUnavailable: 1


# This exposes the Loki gateway so it can be written to and queried externaly
gateway:
  service:
    type: LoadBalancer
  basicAuth:
    enabled: true
    existingSecret: loki-basic-auth

# Since we are using basic auth, we need to pass the username and password to the canary
lokiCanary:
  extraArgs:
    - -pass=$(LOKI_PASS)
    - -user=$(LOKI_USER)
  extraEnv:
    - name: LOKI_PASS
      valueFrom:
        secretKeyRef:
          name: canary-basic-auth
          key: password
    - name: LOKI_USER
      valueFrom:
        secretKeyRef:
          name: canary-basic-auth
          key: username

# Enable minio for storage
minio:
  enabled: false

backend:
  replicas: 0
read:
  replicas: 0
write:
  replicas: 0

singleBinary:
  replicas: 0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&#34;admonition admonition-caution&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Caution&lt;/p&gt;&lt;p&gt;Make sure to replace the placeholders with your actual values.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;



&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;In &lt;code&gt;values.yaml&lt;/code&gt; above, you may notice that &lt;code&gt;serviceAccount&lt;/code&gt; is set to &lt;code&gt;create: false&lt;/code&gt;. This is because you want to use the service account that you created earlier instead of creating a new one.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;It is critical to define a valid &lt;code&gt;values.yaml&lt;/code&gt; file for the Loki deployment. To remove the risk of misconfiguration, let&amp;rsquo;s break down the configuration options to keep in mind when deploying to GCP:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Loki Config vs. Values Config:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;values.yaml&lt;/code&gt; file contains a section called &lt;code&gt;loki&lt;/code&gt;, which contains a direct representation of the Loki configuration file.&lt;/li&gt;
&lt;li&gt;This section defines the Loki configuration, including the schema, storage, and querier configuration.&lt;/li&gt;
&lt;li&gt;The key configuration to focus on for chunks is the &lt;code&gt;storage_config&lt;/code&gt; section, where you define the GCS bucket region and name. This tells Loki where to store the chunks.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;ruler&lt;/code&gt; section defines the configuration for the ruler, including the GCS bucket region and name. This tells Loki where to store the alert and recording rules.&lt;/li&gt;
&lt;li&gt;For the full Loki configuration, refer to the 
    &lt;a href=&#34;/docs/loki/v3.7.x/configure/&#34;&gt;Loki Configuration&lt;/a&gt; documentation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Storage:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Defines where the Helm chart stores data.&lt;/li&gt;
&lt;li&gt;Set the type to &lt;code&gt;GCS&lt;/code&gt; since we are using Google Cloud Storage.&lt;/li&gt;
&lt;li&gt;Configure the bucket names for the chunks and ruler to match the buckets created earlier.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;GCS&lt;/code&gt; section specifies the region of the bucket.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Service Account:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;serviceAccount&lt;/code&gt; section is used to define the IAM role for the Loki service account.&lt;/li&gt;
&lt;li&gt;This is where the IAM role created earlier is linked.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Zone-Aware Replication:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Helm chart enables zone-aware ingester replication by default, which creates three ingester StatefulSets (zone-a, zone-b, zone-c) for faster rollouts.&lt;/li&gt;
&lt;li&gt;In this guide, zone-aware replication is explicitly disabled (&lt;code&gt;ingester.zoneAwareReplication.enabled: false&lt;/code&gt;) for simplicity. For production deployments, consider enabling it to improve rollout resilience.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Gateway:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Defines how the Loki gateway will be exposed.&lt;/li&gt;
&lt;li&gt;We are using a &lt;code&gt;LoadBalancer&lt;/code&gt; service type in this configuration.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;deploy-loki&#34;&gt;Deploy Loki&lt;/h3&gt;
&lt;p&gt;Now that you have created the &lt;code&gt;values.yaml&lt;/code&gt; file, you can deploy Loki using the Helm chart.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Deploy using the newly created &lt;code&gt;values.yaml&lt;/code&gt; file:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm install --values values.yaml loki grafana-community/loki -n loki --create-namespace&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;It is important to create a namespace called &lt;code&gt;loki&lt;/code&gt; as our trust policy is set to allow the IAM role to be used by the &lt;code&gt;loki&lt;/code&gt; service account in the &lt;code&gt;loki&lt;/code&gt; namespace. This is configurable but make sure to update your service account.&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify the deployment:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl get pods -n loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You should see the Loki pods running.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;console&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-console&#34;&gt;NAME                                    READY   STATUS    RESTARTS   AGE
loki-canary-crqpg                       1/1     Running   0          10m
loki-canary-hm26p                       1/1     Running   0          10m
loki-canary-v9wv9                       1/1     Running   0          10m
loki-chunks-cache-0                     2/2     Running   0          10m
loki-compactor-0                        1/1     Running   0          10m
loki-distributor-78ccdcc9b4-9wlhl       1/1     Running   0          10m
loki-distributor-78ccdcc9b4-km6j2       1/1     Running   0          10m
loki-distributor-78ccdcc9b4-ptwrb       1/1     Running   0          10m
loki-gateway-5f97f78755-hm6mx           1/1     Running   0          10m
loki-index-gateway-0                    1/1     Running   0          10m
loki-index-gateway-1                    1/1     Running   0          10m
loki-ingester-zone-a-0                  1/1     Running   0          10m
loki-ingester-zone-b-0                  1/1     Running   0          10m
loki-ingester-zone-c-0                  1/1     Running   0          10m
loki-querier-89d4ff448-4vr9b            1/1     Running   0          10m
loki-querier-89d4ff448-7nvrf            1/1     Running   0          10m
loki-querier-89d4ff448-q89kh            1/1     Running   0          10m
loki-query-frontend-678899db5-n5wc4     1/1     Running   0          10m
loki-query-frontend-678899db5-tf69b     1/1     Running   0          10m
loki-query-scheduler-7d666bf759-9xqb5   1/1     Running   0          10m
loki-query-scheduler-7d666bf759-kpb5q   1/1     Running   0          10m
loki-results-cache-0                    2/2     Running   0          10m
loki-ruler-0                            1/1     Running   0          10m&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;find-the-loki-gateway-service&#34;&gt;Find the Loki Gateway Service&lt;/h3&gt;
&lt;p&gt;The Loki Gateway service is a LoadBalancer service that exposes the Loki gateway to the internet. This is where you will write logs to and query logs from. By default NGINX is used as the gateway.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-caution&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Caution&lt;/p&gt;&lt;p&gt;The Loki Gateway service is exposed to the internet. We provide basic authentication using a username and password in this tutorial. Refer to the 
    &lt;a href=&#34;/docs/loki/v3.7.x/operations/authentication/&#34;&gt;Authentication&lt;/a&gt; documentation for more information.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;To find the Loki Gateway service, run the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl get svc -n loki&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You should see the Loki Gateway service with an external IP address. This is the address you will use to write to and query Loki.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;console&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-console&#34;&gt;NAME           TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)        AGE
loki-gateway   LoadBalancer   34.118.239.140   34.91.203.240   80:30566/TCP   25m&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this case, the external IP address is &lt;code&gt;34.91.203.240&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Congratulations! You have successfully deployed Loki on GCP using the Helm chart. Before we finish, let&amp;rsquo;s test the deployment.&lt;/p&gt;
&lt;h2 id=&#34;testing-your-loki-deployment&#34;&gt;Testing Your Loki Deployment&lt;/h2&gt;
&lt;p&gt;k6 is one of the fastest ways to test your Loki deployment. This will allow you to both write and query logs to Loki. To get started with k6, follow the steps below:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install k6 with the Loki extension on your local machine. Refer to 
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/k6/&#34;&gt;Installing k6 and the xk6-loki extension&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;code&gt;gcp-test.js&lt;/code&gt; file with the following content:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt; import {sleep, check} from &amp;#39;k6&amp;#39;;
 import loki from &amp;#39;k6/x/loki&amp;#39;;

 /**
 * URL used for push and query requests
 * Path is automatically appended by the client
 * @constant {string}
 */

 const username = &amp;#39;&amp;lt;USERNAME&amp;gt;&amp;#39;;
 const password = &amp;#39;&amp;lt;PASSWORD&amp;gt;&amp;#39;;
 const external_ip = &amp;#39;&amp;lt;EXTERNAL-IP&amp;gt;&amp;#39;;

 const credentials = `${username}:${password}`;

 const BASE_URL = `http://${credentials}@${external_ip}`;

 /**
 * Helper constant for byte values
 * @constant {number}
 */
 const KB = 1024;

 /**
 * Helper constant for byte values
 * @constant {number}
 */
 const MB = KB * KB;

 /**
 * Instantiate config and Loki client
 */

 const conf = new loki.Config(BASE_URL);
 const client = new loki.Client(conf);

 /**
 * Define test scenario
 */
 export const options = {
   vus: 10,
   iterations: 10,
 };

 export default () =&amp;gt; {
   // Push request with 10 streams and uncompressed logs between 800KB and 2MB
   var res = client.pushParameterized(10, 800 * KB, 2 * MB);
   // Check for successful write
   check(res, { &amp;#39;successful write&amp;#39;: (res) =&amp;gt; res.status == 204 });

   // Pick a random log format from label pool
   let format = randomChoice(conf.labels[&amp;#34;format&amp;#34;]);

   // Execute instant query with limit 1
   res = client.instantQuery(`count_over_time({format=&amp;#34;${format}&amp;#34;}[1m])`, 1)
   // Check for successful read
   check(res, { &amp;#39;successful instant query&amp;#39;: (res) =&amp;gt; res.status == 200 });

   // Execute range query over last 5m and limit 1000
   res = client.rangeQuery(`{format=&amp;#34;${format}&amp;#34;}`, &amp;#34;5m&amp;#34;, 1000)
   // Check for successful read
   check(res, { &amp;#39;successful range query&amp;#39;: (res) =&amp;gt; res.status == 200 });

   // Wait before next iteration
   sleep(1);
 }

 /**
 * Helper function to get random item from array
 */
 function randomChoice(items) {
   return items[Math.floor(Math.random() * items.length)];
 }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Replace &lt;code&gt;&amp;lt;EXTERNAL-IP&amp;gt;&lt;/code&gt; with the external IP address of the Loki Gateway service.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This script will write logs to Loki and query logs from Loki. It will write logs in a random format between 800KB and 2MB and query logs in a random format over the last 5 minutes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the test:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;./k6 run gcp-test.js&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will run the test and output the results. You should see the test writing logs to Loki and querying logs from Loki.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now that you have successfully deployed Loki in microservices mode on GCP, you may wish to explore the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/loki/v3.7.x/operations/meta-monitoring/&#34;&gt;Monitor a Loki Cluster&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/&#34;&gt;Sending data to Loki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/loki/v3.7.x/query/&#34;&gt;Querying Loki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/loki/v3.7.x/operations/&#34;&gt;Manage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="deploy-the-loki-helm-chart-on-gcp">Deploy the Loki Helm chart on GCP&lt;/h1>
&lt;p>This guide shows how to deploy a minimally viable Loki in &lt;strong>microservices&lt;/strong> mode on Google Cloud Platform (GCP) using the Helm chart. To run through this guide, we expect you to have the necessary tools and permissions to deploy resources on GCP, such as:&lt;/p></description></item></channel></rss>