511 EKS Cluster und mehrere Terraform States [4 PT]

Posted About 1 year ago. Visible to the public.

Im Kapitel 502 Eine Applikation als Container mit CI pipelines deployen hast du eine Applikation auf AWS deployed. In diesem Kapitel wirst du das Setup auf die Verwendung von Kubernetes umbauen und deinen Terraform Code weiter modularisieren.

Ziele

  • Du kannst deinen Terraform Code in mehrere Module und State/Workspaces aufteilen.
  • Du kannst ein EKS Cluster aufsetzen.
  • Du weißt, wie du dich am EKS Cluster authentifizierst.
    • Du verstehst, wie die Authentifizierung funktioniert
  • Du weißt, wie du einem Serviceaccount eine IAM Role zuweisen kannst.
  • Du hast schon einmal Helm verwendet.

Inhalte

Aufgaben

Erstelle Merge Requests für die Code Änderungen und weise sie deinem Mentor zu.

  1. Siehe Multiple Environments with own terraform state unter Inhalte. Du kannst für verschiedene CI Jobs unterschiedliche Terraform states in deinem Gitlab CI verwenden. Dafür verwendet man die Variable TF_STATE_NAME und TF_CLI_ARGS_plan. Du brauchst im Moment nicht mehrere Environments. Aber du solltest dein bisheriges Terraform Modul in mehrere einzelne zerlegen. Das reduziert den "Blast Radius". Allerdings musst du dann neue Wege finden, wie du an Daten von anderen Ressourcen kommst. Nimm folgende Änderungen vor:

    • Das VPC und alles zugehörige (Subnetze, Routen usw) sollte in einem eigenen Modul mit state stecken. Das vpc Show archive.org snapshot modul kann verwendet werden.
    • Die RDS Instanz soll auch ein eigenes Modul sein. Die Daten zum VPC solltest du dir mit data sources holen. Dafür musst du ggf. noch passende Tags zu deinen VPC Ressourcen hinzufügen.
    • Auch ECS Ressourcen ziehst du in ein eigenes Modul mit eigenem State. VPC und RDS Daten kannst du dir mit einer data source holen. Vielleicht musst du auch remote-state verwenden.
  2. Füge ein weiteres Modul für EKS hinzu. EKS ist komplex und es ist zu empfehlen ein fertiges modul wie dieses Show archive.org snapshot zu verwenden. Am besten orientierst du dich an den Examples.

    • Um kubectl zu verwenden musst du deinen IAM Benutzer Zugriff auf das Cluster erlauben. Dafür bietet das EKS Modul die Konfigurationsparameter manage_aws_auth_configmap, aws_auth_node_iam_role_arns_non_windows und aws_auth_roles.
    • Dein EKS Cluster soll eine Nodegroup haben, die nur aus ähnlich großen t* Instanzen besteht. Es sollen nur Spot Instances sein. Achte darauf das VPC Networking Plugin zu verwenden.
    • Außerdem solltest du den AWS Load Balancer Controller Show archive.org snapshot installieren.
    • Achte darauf, dass die Secrets für dein EKS Cluster mit KMS verschlüsselt sind!
  3. Passe dein RDS Modul so an, dass die Verbindungsinformationen (Host, Passwort, User usw.) automatisch als Secret ins Kubernetes gespeichert werden. Der entsprechende Namespace in dem das Secret erstellt wird, sollte vom EKS Modul erstellt werden. Ein Beispiel wie du Daten ins Kubernetes bekommst siehst du hier:

    locals {
      cluster_name = "foobar"
    }
    data "aws_eks_cluster" "default" {
      name = local.cluster_name
    }
    data "aws_eks_cluster_auth" "default" {
      name = local.cluster_name
    }
    provider "kubernetes" {
      host                   = data.aws_eks_cluster.default.endpoint
      cluster_ca_certificate = base64decode(data.aws_eks_cluster.default.certificate_authority[0].data)
      token                  = data.aws_eks_cluster_auth.default.token
    }
    
  4. Erstelle Kubernetes Manifeste um notestar auf EKS zu deployen. Speichere diese gleich in einem Git Repository. Konfiguriere es so, dass die Anwendung mit einem ALB zu erreichen ist. Die Datenbank Verbindungsinformationen kannst du aus dem zuvor erstellten Secret auslesen und als Environment variable injecten. Sorge dafür, dass nicht jeder auf die App zugreifen kann indem du einen Nginx Sidecar Container in deinem Pod konfigurierst der Basic Authentication erfordert.

  5. Installiere den Gitlab Agent für Kubernetes indem du Terraform verwendest um das Helm Chart zu installieren. Im Idealfall wird das token automatisch via GraphQL API erstellt und dann als Config Setting vom Helm übergeben. In diesem Fall ist es aber auch in Ordnung, wenn es manuell als Environment Variable konfiguriert wird. Konfiguration von Helm kann z.B. so aussehen:

    resource "helm_release" "gitlab_agent" {
      name       = "gitlab-kubernetes-agent"
      repository = "https://charts.gitlab.io"
      chart      = "gitlab-agent"
      version    = var.agent_version
    
      namespace        = "gitlab-agent"
      create_namespace = true
    
      values = [
        templatefile("${path.module}/templates/values.yaml.tpl", {
          agent_token       = var.agent_token
          kasAddress        = var.kasAddress
          gitlab_basic_auth = var.gitlab_basic_auth
        })
      ]
    }
    

    Und die dazugehörige values.yaml.tpl file:

    config:
      token: ${agent_token}
      kasAddress: ${kasAddress}
      kasHeaders: 
        - "Authorization: Basic ${gitlab_basic_auth}"
    

    Das makandra gitlab benötigt einen basic auth header, damit sich der gitlab agent verbinden kann. Sprich diesbezüglich mit deinem Mentor.

  6. Konfiguriere den Gitlab Agent für Kubernetes so, dass er deine Manifeste anwendet. Dafür kannst du die bestehenden Ressourcen 1x manuell löschen. Anschließend prüfst du ob die Manifeste angewendet werden.

  7. Wenn du eine neue Version von notestar deployest muss das aktuelle image gepullt werden. Richte dafür einen kubectl rollout job ein. Du musst hier entweder mit Pipeline triggers Show archive.org snapshot oder falls möglich Downstream pipelines Show archive.org snapshot arbeiten.

  8. Mach dir Gedanken wie bei deinen Deployment Jobs eine erfolgreiche Rollback Strategie aussehen könnte. Schau dir z.B. Gitlab deployments an oder überlege dir ein Konzept wie du einfach auf ein altes Release von notestar zurückrollen kannst. Du musst das nicht in der Praxis umsetzen.

  9. Da notestar nun in deinem k8s cluster läuft kannst du deine ECS Infrastruktur deprovisionieren. Außerdem solltest du dokumentieren in welcher Reihenfolge welche Komponenten deployed werden wenn du die Infrastruktur neu Bootstrappen musst. Sämtliche manuelle Schritte sollten auch dokumentiert sein.

Claus-Theodor Riegg
Last edit
9 months ago
Matthias Bruhse
License
Source code in this card is licensed under the MIT License.
Posted by Claus-Theodor Riegg to DevOps Curriculum (2023-01-30 15:05)