Обновление модуля Terraform EKS с версии 17.x до версии 18.x

Если вы, как и я, используете потрясающий модуль terraform-aws-eks для управления кластерами EKS, то вы должны знать, что при обновлении версии модуля с v17.x до v18.x происходит множество ломающих изменений. В этом руководстве я расскажу о шагах, которые я предпринял, чтобы немного облегчить обновление (у нас более 12 кластеров с похожей конфигурацией), и надеюсь, что это кому-нибудь поможет.

Я настоятельно рекомендую вам также ознакомиться с официальным руководством UPGRADE-18.0.md

1) Изменение версии модуля и переменных

Проверьте изменения переменных здесь, так как каждый использует свою конфигурацию, в моем случае я закончил следующим образом:

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

  # check releases for the latest version
  # https://github.com/terraform-aws-modules/terraform-aws-eks/releases
  version = "18.26.2"

  # Needed for EKS module Upgrade
  # https://github.com/terraform-aws-modules/terraform-aws-eks/blob/master/docs/UPGRADE-18.0.md#upgrade-from-v17x-to-v18x
  prefix_separator                   = ""
  iam_role_name                      = var.cluster_name
  cluster_security_group_name        = var.cluster_name
  cluster_security_group_description = "EKS cluster security group."

  # Add this to avoid issues with AWS Load balancer controller
  # "error":"expect exactly one securityGroup tagged kubernetes.io/cluster/xxx
  # https://github.com/terraform-aws-modules/terraform-aws-eks/issues/1986
  node_security_group_tags = {
    "kubernetes.io/cluster/${var.cluster_name}" = null
  }

  cluster_name                    = local.name
  cluster_version                 = local.cluster_version
  cluster_endpoint_private_access = true
  cluster_endpoint_public_access  = true

  cluster_addons = {
    coredns = {
      resolve_conflicts = "OVERWRITE"
    }
    kube-proxy = {
      resolve_conflicts = "OVERWRITE"
    }
  }

  cluster_encryption_config = [
    {
      provider_key_arn = aws_kms_key.eks.arn
      resources        = ["secrets"]
    }
  ]

  vpc_id = module.vpc.vpc_id

  # Rename subnets to subnet_ids
  subnet_ids = module.vpc.private_subnets

  # Rename node_group_defaults to eks_managed_node_group_defaults
  eks_managed_node_group_defaults = {
    ami_type       = "AL2_x86_64"
    instance_types = ["m5.large", "m5a.large", "t3.large", "m5.xlarge"]

    iam_role_attach_cni_policy = true

    update_config = {
      max_unavailable_percentage = 50
    }

    block_device_mappings = {
      xvda = {
        device_name = "/dev/xvda"

        ebs = {
          volume_size = "100"
          volume_type = "gp3"
          encrypted   = true
          kms_key_id  = aws_kms_key.ebs.arn
        }

      }
    }
    metadata_options = {
      http_endpoint               = "enabled"
      http_tokens                 = "required"
      http_put_response_hop_limit = 2
      instance_metadata_tags      = "disabled"
    }
  }
  # Rename eks_managed_node_groups to eks_managed_node_groups
  # the variables in the sub module also changed, so be sure to rename them!
  eks_managed_node_groups = {
    default = {
      name            = "default"
      use_name_prefix = true
      subnet_ids      = module.vpc.private_subnets
      desired_size    = 3
      max_size        = 10
      min_size        = 3

      labels = {
        environment = local.environment
        capacity    = "on_demand"
      }

      tags = local.tags
    },
    spot = {
      name            = "spot"
      use_name_prefix = true
      capacity_type   = "SPOT"
      instance_types  = ["m5a.xlarge", "m5.xlarge", "r5.xlarge", "r5a.xlarge"]
      subnet_ids      = module.vpc.private_subnets
      desired_size    = 3
      max_size        = 15
      min_size        = 3
      cluster_version = local.cluster_version

      labels = {
        environment = local.environment
        capacity    = "spot"
      }

      tags = local.tags
    }
    tags = local.tags
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Если ваша переменная iam_role_name НЕ является именем кластера, получите имя кластерной iam роли с помощью aws cli:

export CLUSTER_NAME=bill-eks-test
aws-vault exec aws-prod -- aws eks describe-cluster --name $CLUSTER_NAME --output json | jq -r .cluster.roleArn | cut -d/ -f2
Войдите в полноэкранный режим Выйдите из полноэкранного режима

2) Сделайте terraform plan, чтобы посмотреть, что изменилось.

Вы должны увидеть, что изменилось множество ресурсов, включая, например, IAM, группы узлов и даже замену плоскости управления кластером (это мы исправим на следующем этапе).

Поскольку изменений много, а мы хотели сделать обновление простым для нас, лучший подход — удалить существующие группы узлов и связанные с ними ресурсы из состояния terraform, это предложение также поступило от пользователей в соответствующем выпуске Github

3) Миграция и удаление состояния Terraform

У всех разные настройки, поэтому будьте осторожны при работе с файлом состояния Terrafrom, так как ваше состояние tf может быть повреждено, всегда сначала делайте резервную копию файла состояния!

# Backup terraform state first 
terraform state pull > tf_backup.tfstate
# Remove node_groups from tf state
terraform state rm 'module.node_groups'
# Rename the cluster iam role tf resource to new name
terraform state mv 'aws_iam_role.cluster[0]' 'aws_iam_role.this[0]'
# Remove policy attachment for node groups from tf state
terraform state rm 'aws_iam_role_policy_attachment.workers_AmazonEC2ContainerRegistryReadOnly[0]' 'aws_iam_role_policy_attachment.workers_AmazonEKSWorkerNodePolicy[0]' 'aws_iam_role_policy_attachment.workers_AmazonEKS_CNI_Policy[0]'
# Remove node groups security group from state
terraform state rm 'aws_security_group.workers[0]'
# Remove node groups aws_security_group_rule resources from tf state
terraform state rm $(terraform state list | grep aws_security_group_rule.workers)
# Remove cluster aws_security_group_rule resources from tf state
terraform state rm $(terraform state list | grep aws_security_group_rule.cluster)
# Remove IAM Role of node groups from tf state
terraform state rm 'aws_iam_role.workers[0]'

# If you are managing the aws-auth configmap using EKS module
# Then remove aws-auth configmap from tf state as now the module dropped the support
terraform state rm 'kubernetes_config_map.aws_auth[0]'

# If you use addons then remove from state as well
terraform state rm 'aws_eks_addon.kube_proxy' 'aws_eks_addon.vpc_cni' 'aws_eks_addon.coredns'
# Then import the new add ons to state
terraform import 'aws_eks_addon.this["coredns"]' cluster:coredns
terraform import 'aws_eks_addon.this["vpc-cni"]' cluster:vpc-cni
terraform import 'aws_eks_addon.this["kube-proxy"]' cluster:kube-proxy
Вход в полноэкранный режим Выход из полноэкранного режима

4) Снова протестируйте терраформный план.

Убедитесь, что вы НЕ видите следующего

  1. Кластер должен быть заменен
  2. Старые группы узлов должны быть уничтожены
  3. Связанные с группами узлов ресурсы (sg, правила sg, старый iam узла) должны быть уничтожены.

Вы должны увидеть следующее:

  1. Некоторые изменения политики кластера.
  2. Добавление новой группы узлов.
  3. Новые ресурсы, связанные с группами узлов.

5) Приступайте к terraform apply.

Теперь вы можете приступить к применению изменений с помощью terraform apply .

После завершения apply вы должны увидеть, что новые узлы присоединились к кластеру и работают, как ожидалось.

6) Вручную удалите старую группу узлов и связанные с ней ресурсы

Теперь вы можете удалить старую группу узлов вручную, и стручки перезапустятся на новых группах узлов 👍 🎉.

Другие связанные ресурсы также должны быть удалены вручную, например, группы безопасности старой узловой группы.

Всего доброго

Понравилась эта статья? Присоединяйтесь ко мне на Medium billhegazy.

Если у вас есть вопросы или вы хотите связаться со мной, добавьте меня в LinkedIn.

Оцените статью
devanswers.ru
Добавить комментарий