Deploying Nginx Ingress and Grafana on Amazon EKS using Terraform Helm Provider

Deploying Nginx Ingress and Grafana on Amazon EKS using Terraform Helm Provider

Deploying applications on Kubernetes requires efficient orchestration and management. In this guide, we’ll explore how to deploy the Nginx Ingress controller and Grafana on Amazon Elastic Kubernetes Service (EKS) using the Terraform Helm provider. Additionally, we’ll create essential infrastructure components such as an EKS cluster, VPC, and subnets.

Prerequisites

Before you proceed, ensure you have the following prerequisites:

  • An AWS account
  • Terraform installed on your machine
  • kubectl installed and configured
  • Helm installed on your machine

Step 1: Setting Up Terraform Configuration

1 - Create a new directory for your Terraform configuration:

mkdir eks-nginx-grafana
cd eks-nginx-grafana

2 - Create a file named main.tf to define your EKS cluster and VPC:

# Main Terraform Configuration

# Provider configurations (AWS)
provider "aws" {
  region = "eu-west-3"  # Replace with your desired region
}

# Module to create VPC and subnets
module "vpc" {
  source = "terraform-aws-modules/vpc/aws"
  
  # Configure your VPC parameters here
}

# Module to create EKS cluster
module "eks_cluster" {
  source = "terraform-aws-modules/eks/aws"
  
  # Configure your EKS cluster parameters here
}

output "eks_config" {
  value = module.eks_cluster
}

You can now init and apply to create the cluster and all dependencies.

Step 2: Deploy Nginx Ingress Controller using Terraform Helm Provider

1 - Create a file named nginx-ingress.tf to deploy the Nginx Ingress controller using the Terraform Helm provider:

# Nginx Ingress Configuration using Helm Provider

# Provider configuration (Helm)
resource "helm_release" "nginx_ingress" {
  name       = "nginx-ingress"
  repository = "https://helm.nginx.com/stable"
  chart      = "nginx-ingress"
  version    = "1.14.2"
  
  set {
    name  = "controller.service.enabled"
    value = "true"
  }

  set {
    name  = "controller.service.type"
    value = "LoadBalancer"
  }

  set {
    name  = "controller.ingressClass"
    value = "nginx"
  }

  set {
    name  = "controller.publishService.enabled"
    value = "true"
  }

  # Add more configuration values as needed
}

You can now apply this configuration to deploy it in your cluster. In this example, we’re configuring various values for the Nginx Ingress controller:

  • controller.service.enabled: Enables the Nginx Ingress controller service.
  • controller.service.type: Specifies the service type for the Nginx Ingress controller (in this case, LoadBalancer).
  • controller.ingressClass: Specifies the Ingress class used by the controller.
  • controller.publishService.enabled: Enables publishing the service.

Step 3: Deploy Grafana using Terraform Helm Provider

1 - Create a file named grafana.tf to deploy Grafana using the Terraform Helm provider:

# grafana.tf

resource "helm_release" "grafana" {
  name       = "grafana"
  repository = "https://grafana.github.io/helm-charts"
  chart      = "grafana"
  version    = "6.16.2"

  set {
    name  = "adminUser"
    value = "admin"
  }

  set {
    name  = "adminPassword"
    value = "your-admin-password"
  }

  set {
    name  = "service.type"
    value = "LoadBalancer"
  }

  set {
    name  = "ingress.enabled"
    value = "true"
  }

  set {
    name  = "ingress.hosts"
    value = ["grafana.your-domain.com"]
  }

  set {
    name  = "ingress.annotations.kubernetes.io/ingress.class"
    value = "nginx"
  }
}

Here is the AIO files (not the best pratice to do it but just an example ):

# main.tf

provider "aws" {
  region = "eu-west-3"  # Replace with your desired region
}

module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = "eks-vpc"

  cidr = "10.0.0.0/16"

  azs             = ["eu-west-3a", "eu-west-3b", "eu-west-3c"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
}

module "eks_cluster" {
  source = "terraform-aws-modules/eks/aws"

  cluster_name = "my-eks-cluster"
  subnets      = module.vpc.private_subnets

  tags = {
    Terraform   = "true"
    Environment = "dev"
  }
}

data "aws_eks_cluster" "eks_cluster" {
  name = module.eks_cluster.cluster_id
}

resource "null_resource" "kubeconfig" {
  provisioner "local-exec" {
    command = "aws eks update-kubeconfig --name ${data.aws_eks_cluster.eks_cluster.name}"
    environment = {
      AWS_DEFAULT_REGION = "eu-west-3"  # Replace with your desired region
    }
  }
  triggers = {
    cluster_id = data.aws_eks_cluster.eks_cluster.id
  }
}

provider "helm" {
  kubernetes {
    config_path = pathexpand("~/.kube/config")
  }
}

resource "helm_release" "nginx_ingress" {
  name       = "nginx-ingress"
  repository = "https://helm.nginx.com/stable"
  chart      = "nginx-ingress"
  version    = "1.14.2"
  
  set {
    name  = "controller.service.enabled"
    value = "true"
  }

  set {
    name  = "controller.service.type"
    value = "LoadBalancer"
  }

  set {
    name  = "controller.ingressClass"
    value = "nginx"
  }

  set {
    name  = "controller.publishService.enabled"
    value = "true"
  }

  # Add more configuration values as needed
}

resource "helm_release" "grafana" {
  name       = "grafana"
  repository = "https://grafana.github.io/helm-charts"
  chart      = "grafana"
  version    = "6.16.2"

  set {
    name  = "adminUser"
    value = "admin"
  }

  set {
    name  = "adminPassword"
    value = "your-admin-password"
  }

  set {
    name  = "service.type"
    value = "LoadBalancer"
  }

  set {
    name  = "ingress.enabled"
    value = "true"
  }

  set {
    name  = "ingress.hosts"
    value = ["grafana.your-domain.com"]
  }

  set {
    name  = "ingress.annotations.kubernetes.io/ingress.class"
    value = "nginx"
  }
}

Conclusion

You have successfully deployed the Nginx Ingress controller and Grafana on Amazon EKS using the Terraform Helm provider. This tutorial provides a fundamental setup to get you started. Depending on your specific needs, you can further customize your Nginx Ingress and Grafana configurations.