Hi all, this post just to share my code and experience on deploying kubernetes dashboard terraform.
1. Terraform
2. AKS (Azure Kubernetes Service)
3. k2tf
If anyone did test AKS, it does provide its own view on the cluster information together with all the pod that has been deploy. However, for me there are some view that is missing which the load of each pod received is no there in the portal. It may work if the AKS has sent the log to Log Analytic and the AKS workbook is configure.
Just for this case, the Log analytic is not present due to some reason as in this cluster just for development. There some guide provided via microsoft docs since im using AKS and the Kubernetes itself, how ever , those guide is not deploy via "Kubectl" which is ok . As i did the AKS deployment via terraform, why not put that dashboard deployment together so it will appear one the cluster is deployed.
So here is what i did, is download the deployment.yaml for k8s dashboard and convert to terraform (.yaml to .tf). For that, i have discover one useful tool to convert it which is K2TF .
provider "kubernetes" {
#load_config_file = "false"
host = var.host
client_certificate = var.client_certificate
client_key = var.client_key
cluster_ca_certificate = var.cluster_ca_certificate
}
resource "null_resource" "main" {
provisioner "local-exec" {
command = "az aks disable-addons -g ${var.aks-rg} -n ${var.aks-name} -a kube-dashboard"
}
}
resource "kubernetes_namespace" "kubernetes_dashboard" {
metadata {
name = "kubernetes-dashboard"
}
}
resource "kubernetes_service_account" "kubernetes_dashboard" {
metadata {
name = "kubernetes-dashboard"
namespace = "kubernetes-dashboard"
labels = {
k8s-app = "kubernetes-dashboard"
}
}
}
resource "kubernetes_service" "kubernetes_dashboard" {
metadata {
name = "kubernetes-dashboard"
namespace = "kubernetes-dashboard"
labels = {
k8s-app = "kubernetes-dashboard"
}
}
spec {
port {
port = 443
target_port = "8443"
}
selector = {
k8s-app = "kubernetes-dashboard"
}
}
}
resource "kubernetes_secret" "kubernetes_dashboard_certs" {
metadata {
name = "kubernetes-dashboard-certs"
namespace = "kubernetes-dashboard"
labels = {
k8s-app = "kubernetes-dashboard"
}
}
type = "Opaque"
}
resource "kubernetes_secret" "kubernetes_dashboard_csrf" {
metadata {
name = "kubernetes-dashboard-csrf"
namespace = "kubernetes-dashboard"
labels = {
k8s-app = "kubernetes-dashboard"
}
}
type = "Opaque"
}
resource "kubernetes_secret" "kubernetes_dashboard_key_holder" {
metadata {
name = "kubernetes-dashboard-key-holder"
namespace = "kubernetes-dashboard"
labels = {
k8s-app = "kubernetes-dashboard"
}
}
type = "Opaque"
}
resource "kubernetes_config_map" "kubernetes_dashboard_settings" {
metadata {
name = "kubernetes-dashboard-settings"
namespace = "kubernetes-dashboard"
labels = {
k8s-app = "kubernetes-dashboard"
}
}
}
resource "kubernetes_role" "kubernetes_dashboard" {
metadata {
name = "kubernetes-dashboard"
namespace = "kubernetes-dashboard"
labels = {
k8s-app = "kubernetes-dashboard"
}
}
rule {
verbs = ["get", "update", "delete"]
api_groups = [""]
resources = ["secrets"]
resource_names = ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
}
rule {
verbs = ["get", "update"]
api_groups = [""]
resources = ["configmaps"]
resource_names = ["kubernetes-dashboard-settings"]
}
rule {
verbs = ["proxy"]
api_groups = [""]
resources = ["services"]
resource_names = ["heapster", "dashboard-metrics-scraper"]
}
rule {
verbs = ["get"]
api_groups = [""]
resources = ["services/proxy"]
resource_names = ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
}
}
resource "kubernetes_cluster_role" "kubernetes_dashboard" {
metadata {
name = "kubernetes-dashboard"
labels = {
k8s-app = "kubernetes-dashboard"
}
}
rule {
verbs = ["get", "list", "watch"]
api_groups = ["metrics.k8s.io"]
resources = ["pods", "nodes"]
}
}
resource "kubernetes_role_binding" "kubernetes_dashboard" {
metadata {
name = "kubernetes-dashboard"
namespace = "kubernetes-dashboard"
labels = {
k8s-app = "kubernetes-dashboard"
}
}
subject {
kind = "ServiceAccount"
name = "kubernetes-dashboard"
namespace = "kubernetes-dashboard"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "Role"
name = "kubernetes-dashboard"
}
}
resource "kubernetes_cluster_role_binding" "kubernetes_dashboard" {
metadata {
name = "kubernetes-dashboard"
}
subject {
kind = "ServiceAccount"
name = "kubernetes-dashboard"
namespace = "kubernetes-dashboard"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = "kubernetes-dashboard"
}
}
resource "kubernetes_deployment" "kubernetes_dashboard" {
metadata {
name = "kubernetes-dashboard"
namespace = "kubernetes-dashboard"
labels = {
k8s-app = "kubernetes-dashboard"
}
}
spec {
replicas = 1
selector {
match_labels = {
k8s-app = "kubernetes-dashboard"
}
}
template {
metadata {
labels = {
k8s-app = "kubernetes-dashboard"
}
}
spec {
volume {
name = "kubernetes-dashboard-certs"
secret {
secret_name = "kubernetes-dashboard-certs"
}
}
volume {
name = "tmp-volume"
#empty_dir = {}
}
container {
name = "kubernetes-dashboard"
image = "kubernetesui/dashboard:v2.4.0"
args = ["--auto-generate-certificates", "--namespace=kubernetes-dashboard"]
port {
container_port = 8443
protocol = "TCP"
}
volume_mount {
name = "kubernetes-dashboard-certs"
mount_path = "/certs"
}
volume_mount {
name = "tmp-volume"
mount_path = "/tmp"
}
liveness_probe {
http_get {
path = "/"
port = "8443"
scheme = "HTTPS"
}
initial_delay_seconds = 30
timeout_seconds = 30
}
image_pull_policy = "Always"
security_context {
run_as_user = 1001
run_as_group = 2001
read_only_root_filesystem = true
}
}
node_selector = {
"kubernetes.io/os" = "linux"
}
service_account_name = "kubernetes-dashboard"
toleration {
key = "node-role.kubernetes.io/master"
effect = "NoSchedule"
}
}
}
revision_history_limit = 10
}
}
resource "kubernetes_service" "dashboard_metrics_scraper" {
metadata {
name = "dashboard-metrics-scraper"
namespace = "kubernetes-dashboard"
labels = {
k8s-app = "dashboard-metrics-scraper"
}
}
spec {
port {
port = 8000
target_port = "8000"
}
selector = {
k8s-app = "dashboard-metrics-scraper"
}
}
}
resource "kubernetes_deployment" "dashboard_metrics_scraper" {
metadata {
name = "dashboard-metrics-scraper"
namespace = "kubernetes-dashboard"
labels = {
k8s-app = "dashboard-metrics-scraper"
}
}
spec {
replicas = 1
selector {
match_labels = {
k8s-app = "dashboard-metrics-scraper"
}
}
template {
metadata {
labels = {
k8s-app = "dashboard-metrics-scraper"
}
}
spec {
volume {
name = "tmp-volume"
#empty_dir = {}
}
container {
name = "dashboard-metrics-scraper"
image = "kubernetesui/metrics-scraper:v1.0.7"
port {
container_port = 8000
protocol = "TCP"
}
volume_mount {
name = "tmp-volume"
mount_path = "/tmp"
}
liveness_probe {
http_get {
path = "/"
port = "8000"
scheme = "HTTP"
}
initial_delay_seconds = 30
timeout_seconds = 30
}
security_context {
run_as_user = 1001
run_as_group = 2001
read_only_root_filesystem = true
}
}
node_selector = {
"kubernetes.io/os" = "linux"
}
service_account_name = "kubernetes-dashboard"
toleration {
key = "node-role.kubernetes.io/master"
effect = "NoSchedule"
}
}
}
revision_history_limit = 10
}
}
# resource "null_resource" "proxy" {
# provisioner "local-exec" {
# command = "kubectl proxy"
# }
# }
# resource "null_resource" "web" {
# provisioner "local-exec" {
# command = "start-process http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/pod?namespace=default"
# }
# }
so , if you are keen to do like i did , you may copy the code and run it together with your terraform for AKS deployment.