Provisionando EKS com Terraform

bernardo

Luiz Bernardo

Posted on March 7, 2022

Provisionando EKS com Terraform

O Amazon Elastic Kubernetes Service (EKS) é o serviço da AWS para implantar, gerenciar e dimensionar aplicativos em contêiner com Kubernetes.

Veja aqui alguns benefícios do EKS.

O EKS abstrai bastante esforço quanto a HA por ser gerenciado e ter uma configuração de autoscaling simples.

Beleza, então vamos instalar um EKS com Terraform nesse post.

1. Crie algumas configurações de ambiente

Crie um arquivo .tf com configurações gerais. No exemplo criei um arquivo main.tf.

# main.tf
## região que você criará os recursos:
variable "region" {
  default     = "us-east-1"
  description = "AWS region"
}

## provider que você utilizará, nesse exemplo vou estar utilizando apenas AWS
provider "aws" {
  region = var.region
}

## em qual AZ vc quer criar esse recurso, no caso estou selecionando qualquer uma disponível
data "aws_availability_zones" "available" {}
## qual será o nome do seu cluster, estou usando um sufixo apenas para evitar falhas e não tenho muita criatividade
locals {
  cluster_name = "brbernardo-eks-${random_string.suffix.result}"
}

resource "random_string" "suffix" {
  length  = 8
  special = false
}

Enter fullscreen mode Exit fullscreen mode

2. Crie a VPC

Para esse exemplo vou utilizar o módulo oficial de criação de VPC da AWS e passar alguns parâmetros simples.

# vpc.tf
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "3.2.0"

  name                 = "brbernardo-eks-vpc"
  cidr                 = "10.0.0.0/16"
  azs                  = data.aws_availability_zones.available.names
  private_subnets      = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets       = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"]
  enable_nat_gateway   = true
  single_nat_gateway   = true
  enable_dns_hostnames = true

  tags = {
    "kubernetes.io/cluster/${local.cluster_name}" = "shared"
  }

  public_subnet_tags = {
    "kubernetes.io/cluster/${local.cluster_name}" = "shared"
    "kubernetes.io/role/elb"                      = "1"
  }

  private_subnet_tags = {
    "kubernetes.io/cluster/${local.cluster_name}" = "shared"
    "kubernetes.io/role/internal-elb"             = "1"
  }
}

Enter fullscreen mode Exit fullscreen mode

3. Crie os security groups

Nesta etapa vamos criar o SG mgmt e workers.
Isso é um pré-requisito obrigatório para o funcionamento do EKS.

# security-groups.tf
resource "aws_security_group" "worker_group_mgmt_one" {
  name_prefix = "worker_group_mgmt_one"
  vpc_id      = module.vpc.vpc_id

  ingress {
    from_port = 22
    to_port   = 22
    protocol  = "tcp"

    cidr_blocks = [
      "10.0.0.0/8",
    ]
  }
}

resource "aws_security_group" "worker_group_mgmt_two" {
  name_prefix = "worker_group_mgmt_two"
  vpc_id      = module.vpc.vpc_id

  ingress {
    from_port = 22
    to_port   = 22
    protocol  = "tcp"

    cidr_blocks = [
      "192.168.0.0/16",
    ]
  }
}

resource "aws_security_group" "all_worker_mgmt" {
  name_prefix = "all_worker_management"
  vpc_id      = module.vpc.vpc_id

  ingress {
    from_port = 22
    to_port   = 22
    protocol  = "tcp"

    cidr_blocks = [
      "10.0.0.0/8",
      "172.16.0.0/12",
      "192.168.0.0/16",
    ]
  }
}

Enter fullscreen mode Exit fullscreen mode

4. Crie as configurações de acesso ao cluster

Nesta etapa vamos basicamente criar o token de acesso ao cluster EKS utilizando o provider kubernetes.

# kubernetes.tf
provider "kubernetes" {
  host                   = data.aws_eks_cluster.cluster.endpoint
  cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority.0.data)
  exec {
    api_version = "client.authentication.k8s.io/v1alpha1"
    args        = ["eks", "get-token", "--cluster-name", data.aws_eks_cluster.cluster.name]
    command     = "aws"
  }
}

Enter fullscreen mode Exit fullscreen mode

5. Crie o EKS

Finalmente vamos juntar tudo e criar o .tf para criação do EKS. Todas as etapas anteriores são os requisitos mínimos para o provisionamento do EKS, porém há mais configurações que podem ser acrescentadas.

# eks-cluster.tf
module "eks" {
  source          = "terraform-aws-modules/eks/aws"
  version         = "17.24.0"
  cluster_name    = local.cluster_name
  cluster_version = "1.21"
  subnets         = module.vpc.private_subnets
  cluster_endpoint_private_access = true
  cluster_endpoint_public_access  = true
  vpc_id = module.vpc.vpc_id



  workers_group_defaults = {
    root_volume_type = "gp2"
  }

  worker_groups = [
    {
      name                          = "worker-group-1"
      instance_type                 = "t2.small"
      additional_userdata           = "echo foo bar"
      additional_security_group_ids = [aws_security_group.worker_group_mgmt_one.id]
      iam_role_additional_policies           = ["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"]
      update_launch_template_default_version = true
      asg_desired_capacity          = 2
    },
    {
      name                          = "worker-group-2"
      instance_type                 = "t2.medium"
      additional_userdata           = "echo foo bar"
      additional_security_group_ids = [aws_security_group.worker_group_mgmt_two.id]
      iam_role_additional_policies           = ["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"]
      update_launch_template_default_version = true
      asg_desired_capacity          = 1
    },
  ]
}

resource "aws_kms_key" "eks" {
  description             = "EKS Secret Encryption Key"
  deletion_window_in_days = 7
  enable_key_rotation     = true
}

data "aws_eks_cluster" "cluster" {
  name = module.eks.cluster_id
}

data "aws_eks_cluster_auth" "cluster" {
  name = module.eks.cluster_id
}

Enter fullscreen mode Exit fullscreen mode

6. Crie o outputs

O outputs.tf será importante para a configuração do kubectl posteriormente

# outputs.tf
output "cluster_id" {
  description = "EKS cluster ID."
  value       = module.eks.cluster_id
}

output "cluster_endpoint" {
  description = "Endpoint for EKS control plane."
  value       = module.eks.cluster_endpoint
}

output "cluster_security_group_id" {
  description = "Security group ids attached to the cluster control plane."
  value       = module.eks.cluster_security_group_id
}

output "kubectl_config" {
  description = "kubectl config as generated by the module."
  value       = module.eks.kubeconfig
}

output "config_map_aws_auth" {
  description = "A kubernetes configuration to authenticate to this EKS cluster."
  value       = module.eks.config_map_aws_auth
}

output "region" {
  description = "AWS region"
  value       = var.region
}

output "cluster_name" {
  description = "Kubernetes Cluster Name"
  value       = local.cluster_name
}

Enter fullscreen mode Exit fullscreen mode

Se estiver tudo certo seu diretório estará assim

Terraform-EKS
│   eks-cluster.tf
│   kubernetes.tf
│   main.tf
│   outputs.tf
│   security-groups.tf
│   vpc.tf

Enter fullscreen mode Exit fullscreen mode

Estando tudo certo, agora é só executar os comando init e apply

$ terraform init && terraform apply -auto-approve
Enter fullscreen mode Exit fullscreen mode

O provisionamento demora cerca de 20 minutos, então estique as pernas e tome um café.

Estando tudo certo você estara com seu EKS minimamente configurado e ativo.

Para configurar o kubectl execute esse comando


$ aws eks --region $(terraform output -raw region) update-kubeconfig --name $(terraform output -raw cluster_name)

Enter fullscreen mode Exit fullscreen mode

É isso por hoje.
Vlw flw

💖 💪 🙅 🚩
bernardo
Luiz Bernardo

Posted on March 7, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related