A equipe CodePipeline da Amazon Web Services (AWS) simplificou a sobrecarga operacional dos desenvolvedores e engenheiros DevOps e agilizou o processo de implantação no EKS ao introduzir uma ação CodePipeline para implantar diretamente no seu cluster EKS.
Por que isso importa para você?
Antes, se eu tivesse que implantar recursos no EKS usando a abordagem DevOps, tinha que gerenciar o projeto de codebuild, permissões para acessar EKS, kubectl, comandos helm, outros comandos horríveis de shell, e ainda assim não ficava perfeito de uma vez só.
Testei isso hoje, então deixe-me mostrar como você pode simplificar seu pipeline de implantação para EKS em 100%, diga adeus ao codebuild e remova todo o processo, scripts e comandos complexos!!
Arquitetura

Pré-requisitos
- Cluster EKS com endpoint público.
- Kubernetes resource like deployment.yaml file
- Você também pode fazer o quadro, se quiser.
Nota: Se você quiser tentar esta atualização com o EKS Private Endpoint, confira este blog do AWS Hero Arshad Zackeriya.
Qualquer que você preferir, disponibilizei ambos (helm chart e deployment.yaml) neste repositório.
Nos Bastidores
No caso do arquivo de manifestos do Kubernetes

- Essa ação registra no EKS cluster, define o contexto kubeconfig
- Installs kubectl
- Aplica manifestos Kubernetes
- Recursos de implementação
No caso do leme gráfico
- Essa ação registra no EKS cluster, define o contexto kubeconfig
- Instala o leme
- Gráficos Instal Helm
Criar um cluster EKS
Seu cluster pode ser público ou privado (incluindo aqueles em VPCs privadas). O pipeline estabelecerá automaticamente uma conexão com sua rede privada para implantar sua aplicação container, sem necessidade de infraestrutura adicional.
- Eu usei o EKS Auto usando o módulo EKS do terraform , que é rápido e fácil com o endpoint EKS como público.
eks.tf
# EKS cluster módulo "eks" { fonte = "terraform-aws-modules/eks/aws" versão = "~> 20.31" cluster_name = local.cluster_name cluster_version = "1,32" cluster_endpoint_public_access = verdadeiro vpc_id = module.vpc.vpc_id subnet_ids = module.vpc.private_subnets cluster_compute_config = { ativado = verdadeiro node_pools = ["uso geral"] } # Entrada de acesso ao cluster # Para adicionar a identidade atual do chamador como administrador enable_cluster_creator_admin_permissions = verdadeiro tags = { Ambiente = "dev" Terraformação = "verdadeiro" } }
vpc.tf
módulo "vpc" { fonte = "terraform-aws-modules/vpc/aws" versão = "5.19.0" nome = "codepipeline-eks-action" cidr = "10.0.0.0/16" azs = ["EUA-Leste-1A", "EUA-Leste-1B"] private_subnets = ["10.0.1.0/24", "10.0.2.0/24"] public_subnets = ["10.0.4.0/24", "10.0.5.0/24"] enable_nat_gateway = verdadeiro single_nat_gateway = verdadeiro one_nat_gateway_per_az = falso enable_dns_hostnames = verdadeiro enable_dns_support = verdadeiro public_subnet_tags = { "kubernetes.io/role/elb" = "1" } private_subnet_tags = { "kubernetes.io/role/internal-elb" = "1" } tags = { Ambiente = "terraform-playground" } }
pod_identity.tf
data "aws_iam_policy_document" "allow_pod_identity" { afirmação { efeito = "Permitir" diretores { tipo = "Serviço" identificadores = ["pods.eks.amazonaws.com"] } ações = [ "sts:AssumeRole", "sts:TagSession" ] } } recurso "aws_iam_role" "read_ecr" { nome = "read-ecr-role" assume_role_policy = data.aws_iam_policy_document.allow_pod_identity.json } recurso "aws_iam_role_policy_attachment" "read_ecr" { função = aws_iam_role.read_ecr.name policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" } recurso "aws_eks_pod_identity_association" "read_ecr" { cluster_name = local.cluster_name namespace = "padrão" service_account = "ecr-sa" role_arn = aws_iam_role.read_ecr.arn }
Nota: Estou usando a identidade do pod com permissão do repositório ECR para obter a imagem ecr para deployment.yaml.
Se você quiser código completo para o cluster, pode seguir este repositório
Criar pipeline com ação de implantação do EKS
Caso 1: quando a configuração kubectl é usada.
Estou usando o código-fonte como GitHub usando a conexão de início do código e o código reside neste repositório
- Selecione o cluster
- Forneça o caminho para seu arquivo deployment.yaml (no meu caso, é o arquivo deployment.yaml )
Caso 2: Quando o mapa de Helm é usado
- Insira o nome do lançamento
- Insira o gráfico do helm (no meu caso é o gráfico de teste)
Passo importante
Nota: Uma vez que o pipeline é criado, você precisa editar o papel de serviço do pipeline ou atualizar o existente e adicionar as seguintes permissões para evitar erros.
{ "Declaração": [ { "Ação": [ "iam:PassRole" ], "Resource": "*", "Efeito": "Permitir", "Condição": { "StringEqualsIfExists": { "iam:PassedToService": [ "cloudformation.amazonaws.com", "elasticbeanstalk.amazonaws.com", "ec2.amazonaws.com", "ecs-tasks.amazonaws.com" ] } } }, { "Ação": [ "codecommit:CancelUploadArchive", "codecommit:GetBranch", "codecommit:GetCommit", "codecommit:GetRepository", "codecommit:GetUploadArchiveStatus", "codecommit:UploadArchive" ], "Resource": "*", "Efeito": "Permitir" }, { "Ação": [ "codedeploy:CreateDeployment", "codedeploy:GetApplication", "codedeploy:GetApplicationRevision", "codedeploy:GetDeployment", "codedeploy:GetDeploymentConfig", "codedeploy:RegisterApplicationRevision" ], "Resource": "*", "Efeito": "Permitir" }, { "Ação": [ "codestar-connections:UseConnection" ], "Resource": "*", "Efeito": "Permitir" }, { "Ação": [ "pé de feijão elástico:*", "ec2:*", "equilíbrio de carga elástica:*", "autoscaling:*", "Cloudwatch:*", "s3:*", "sns:*", "formação de nuvens:*", "rds:*", "sqs:*", "ECS:*" ], "Resource": "*", "Efeito": "Permitir" }, { "Ação": [ "lambda:InvokeFunction", "lambda:ListFunctions" ], "Resource": "*", "Efeito": "Permitir" }, { "Ação": [ "opsworks:CreateDeployment", "opsworks:DescribeApps", "opsworks:DescribeCommands", "opsworks:DescreveImplantações", "opsworks:DescribeInstances", "opsworks:DescribeStacks", "opsworks:UpdateApp", "opsworks:UpdateStack" ], "Resource": "*", "Efeito": "Permitir" }, { "Ação": [ "cloudformation:CreateStack", "cloudformation:DeleteStack", "cloudformation:DescribeStacks", "cloudformation:UpdateStack", "cloudformation:CreateChangeSet", "cloudformation:DeleteChangeSet", "cloudformation:DescribeChangeSet", "cloudformation:ExecuteChangeSet", "cloudformation:SetStackPolicy", "cloudformation:ValidateTemplate" ], "Resource": "*", "Efeito": "Permitir" }, { "Ação": [ "codebuild:BatchGetBuilds", "codebuild:StartBuild", "codebuild:BatchGetBuildBatches", "codebuild:StartBuildBatch" ], "Resource": "*", "Efeito": "Permitir" }, { "Efeito": "Permitir", "Ação": [ "devicefarm:ListProjects", "fazenda de dispositivos:ListDevicePools", "devicefarm:GetRun", "devicefarm:GetUpload", "devicefarm:CreateUpload", "devicefarm:ScheduleRun" ], "Recurso": "*" }, { "Efeito": "Permitir", "Ação": [ "servicecatalog:ListProvisioningArtifacts", "servicecatalog:CreateProvisioningArtifact", "servicecatalog:DescribeProvisioningArtifact", "servicecatalog:DeleteProvisioningArtifact", "servicecatalog:UpdateProduct" ], "Recurso": "*" }, { "Efeito": "Permitir", "Ação": [ "cloudformation:ValidateTemplate" ], "Recurso": "*" }, { "Efeito": "Permitir", "Ação": [ "ecr:DescribeImages" ], "Recurso": "*" }, { "Efeito": "Permitir", "Ação": [ "afirma: Descrever a Execução", "estados:DescreveEstadoMáquina", "afirma: IniciarExecução" ], "Recurso": "*" }, { "Efeito": "Permitir", "Ação": [ "appconfig:StartDeployment", "appconfig:StopDeployment", "appconfig:GetDeployment" ], "Recurso": "*" }, { "Efeito": "Permitir", "Ação": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Recurso": [ "arn:aws:logs:us-east-1:xxxx:log-group:/aws/codepipeline/eks-deploy-codepipeline", "arn:aws:logs:us-east-1:xxxxx:log-group:/aws/codepipeline/eks-deploy-codepipeline:log-stream:*" ] }, { "Sid": "EksClusterPolicy", "Efeito": "Permitir", "Ação": "eks:DescribeCluster", "Recurso": [ "*" ] }, { "Sid": "EksVpcClusterPolicy", "Efeito": "Permitir", "Ação": [ "ec2:DescribeDhcpOptions", "ec2:DescribeNetworkInterfaces", "ec2:DescribeRouteTables", "ec2:DescribeSubnets", "ec2:DescribeSecurityGroups", "ec2:DescribeVpcs" ], "Recurso": [ "*" ] }, { "Efeito": "Permitir", "Ação": "ec2:CreateNetworkInterface", "Resource": "*", "Condição": { "StringEqualsIfExists": { "ec2:Subnet": [ "arn:aws:ec2:us-east-1:292170836962:exemplo-subrede/subrede1", "arn:aws:ec2:us-east-1:292170836962:subnet/subnet-example2" ] } } }, { "Efeito": "Permitir", "Ação": "ec2:CreateNetworkInterfacePermission", "Resource": "*", "Condição": { "ArnEquals": { "ec2:Subnet": [ "arn:aws:ec2:us-east-1:xxxx:subnet/subnet-example1", "arn:aws:ec2:us-east-1:xxxx:subnet/subnet-example2" ] } } }, { "Efeito": "Permitir", "Ação": "ec2:DeleteNetworkInterface", "Resource": "*", "Condição": { "StringEqualsIfExists": { "ec2:Subnet": [ "arn:aws:ec2:us-east-1:xxxxx:exemplo-subrede/subnet1", "arn:aws:ec2:us-east-1:xxxx:subnet/subnet-example2" ] } } } ], "Versão": "2012-10-17" }
- Crie uma entrada de acesso no EKS cluster com AmazonEKSClusterAdminPolicy para a função de serviço codepipeline acima.
Execute o oleoduto
Caso quando o manifesto de kubectl for atualizado
(base) jatin.mehrotra@CK0662-001 codepipeline-eks-deployment-no-github % kubectl get pods NOME E STATUS PRONTO REINICIA IDADE hello-k8s-74fd98b69b-2pwrv 1/1 Rodando 0 2m37s hello-k8s-74fd98b69b-g876f 1/1 Rodando 0 2m37s hello-k8s-74fd98b69b-phs77 1/1 Correndo 0 2m37s
Caso quando o manifesto do mapa do leme for atualizado
(base) jatin.mehrotra@CK0662-001 codepipeline-eks-deployment-no-github % kubectl get pods NOME E STATUS PRONTO REINICIA IDADE teste-67cbfddc66-2gcvj 1/1 Correndo 0 10m
Do ponto de vista do desenvolvedor, DevOps
- Com essa atualização, não preciso gerenciar projetos de codebuild ou qualquer tipo de ambiente de computação, nem gerenciar scripts complexos, permissões e instalações de ferramentas.
- A seguir está a imagem da configuração que eu costumava ter com o codebuild antes desta atualização. Uma bagunça tão complexa.
- Isso certamente é um divisor de águas para desenvolvedores, engenheiros DevOps e engenheiros de infraestrutura que querem focar em problemas de negócios, suas aplicações e outras questões do Kubernetes como monitoramento e escalabilidade.
Essa não é uma abordagem GitOps, que é seguida pelo Flux/ArgoCD, mas sim a melhor abordagem DevOps para cluster EKS, na minha opinião.
Eu compartilho atualizações incríveis da AWS sobre DevOps, Kubernetes e GenAI diariamente em Linkedin, X. Me siga por lá para que eu possa facilitar sua vida.