Usando o ArgoCD para gerenciar recursos na AWS

O conteúdo deste tutorial é fruto de uma PoC realizada em conjunto com Isaac Mecchi e Guilherme Aguiar entre os dias 02/Abril e 07/Maio de 2024.

Sobre Gitops e ArgoCD

Em outro tutorial, eu falei sobre a abordagem GitOps e uso do Argo CD para deploy de aplicações em clusters Kubernetes… Recomendo a leitura para entender alguns conceitos antes de partir para o assunto que será explicado aqui.

Sobre o ACK

AWS Controllers for Kubernetes (ACK) permite definir e usar recursos de serviço da AWS diretamente do Kubernetes. Com o ACK, você pode aproveitar os serviços gerenciados pela AWS para seus aplicativos Kubernetes sem precisar definir recursos fora do cluster ou executar serviços que fornecem recursos de suporte, como bancos de dados ou filas de mensagens dentro do cluster.

É uma outra forma de gerenciar recursos da AWS que serve de alternativa ao que já sabemos fazer com Terraform/Terragrunt, que permite usar o que há de melhor na abordagem GitOps e dar mais autonomia aos desenvolvedores.

Para saber mais informações sobre o ACK recomendo a leitura das páginas:

Requisitos

Para executar os passos deste tutorial é necessário ter as seguintes ferramentas instaladas:

O procedimento de instalação de cada uma delas não será abordado aqui para não ficar muito longo, mas você pode encontrar o procedimento de instalação na documentação oficial.

Instalando o ArgoCD no Kubernetes

Instale o ArgoCD seguindo as instruções das seções abaixo contidas nesse tutorial: https://blog.aeciopires.com/usando-o-argo-cd-para-implementar-a-abordagem-gitops-nos-clusters-kubernetes/

  • Instalando o Argo CD
  • Instalando o Argo CD CLI (Command Line Interface)

Instalando o ACK de lambda

Para cada tipo de recurso da AWS, existe um controller do ACK específico que irá gerenciar CRDs dentro do cluster Kubernetes.
Neste tutorial será utilizado apenas o controller de lambda.

Referências:

Execute os seguintes comandos:

Lembre-se de alterar os trechos que possuem o termo CHANGE_HERE.

export SERVICE=lambda

export RELEASE_VERSION=$(curl -sL https://api.github.com/repos/aws-controllers-k8s/${SERVICE}-controller/releases/latest | jq -r '.tag_name | ltrimstr("v")')

export ACK_SYSTEM_NAMESPACE=ack-system

export AWS_REGION=CHANGE_HERE

export AWS_PROFILE=CHANGE_HERE

kubectl create namespace $ACK_SYSTEM_NAMESPACE

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: aws-creds
  namespace: "$ACK_SYSTEM_NAMESPACE"
type: Opaque
stringData:
  credentials: |
    [default]
    aws_region=CHANGE_HERE
    aws_access_key_id=CHANGE_HERE
    aws_secret_access_key=CHANGE_HERE
EOF


cat <<EOF > $HOME/ack/lambda_values.yaml
aws:
  # If specified, use the AWS region for AWS API calls
  region: "us-east-1"
  endpoint_url: ""
  credentials:
    # If specified, Secret with shared credentials file to use.
    secretName: "aws-creds"
    # Secret stringData key that contains the credentials
    secretKey: "credentials"
    # Profile used for AWS credentials
    profile: "default"
EOF

aws ecr-public get-login-password --region $AWS_REGION --profile $AWS_PROFILE | helm registry login --username AWS --password-stdin public.ecr.aws

helm upgrade --install --create-namespace -n $ACK_SYSTEM_NAMESPACE ack-$SERVICE-controller \
  oci://public.ecr.aws/aws-controllers-k8s/$SERVICE-chart --version=$RELEASE_VERSION --set=aws.region=$AWS_REGION --values=$HOME/ack/lambda_values.yaml

Criando uma lambda via ACK (apenas para validar o funcionamento)

A ideia é remover no final e criar a lambda usando o ArgoCD + ACK

Referências:

Execute os seguintes comandos:

Lembre-se de alterar os trechos que possuem o termo CHANGE_HERE.
# Compilando a imagem docker
export AWS_REGION=CHANGE_HERE

export AWS_PROFILE=CHANGE_HERE

export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text --profile $AWS_PROFILE --region $AWS_REGION)

export REMOTE_DOCKER_IMAGE='aecio-test-ack-lambda-hello-world'


aws ecr get-login-password --region $AWS_REGION --profile $AWS_PROFILE | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com

aws ecr create-repository --profile $AWS_PROFILE --region $AWS_REGION --repository-name $REMOTE_DOCKER_IMAGE --image-scanning-configuration scanOnPush=false --image-tag-mutability MUTABLE

docker tag  "hello-world:latest" "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/$REMOTE_DOCKER_IMAGE:latest"

docker push "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/$REMOTE_DOCKER_IMAGE:latest"

Crie manualmente uma role para ser usada pela lambda

Foi criada uma role relacionando o serviço de lambda e a policy gerenciada ‘Adminstrator_Access‘.

Deploy da lambda com o ACK

Referências:

Execute os seguintes comandos:

Lembre-se de alterar os trechos que possuem o termo CHANGE_HERE.
export IMAGE_URI="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/$REMOTE_DOCKER_IMAGE:latest"

export FUNCTION_NAME="aecio-ack-lambda-hello-word"

# Role criada manualmente relacionando o serviço de lambda e a policy gerenciada 'Adminstrator_Access'
export LAMBDA_ROLE="arn:aws:iam::${AWS_ACCOUNT_ID}:role/$FUNCTION_NAME"

read -r -d '' LAMBDA_MANIFEST <<EOF
apiVersion: lambda.services.k8s.aws/v1alpha1
kind: Function
metadata:
 name: $FUNCTION_NAME
 namespace: default
 annotations:
   services.k8s.aws/region: $AWS_REGION
spec:
 name: $FUNCTION_NAME
 packageType: Image
 code:
     imageURI: $IMAGE_URI
 role: $LAMBDA_ROLE
 description: function created by ACK lambda-controller e2e tests
 environment:
  variables:
    NAME: "ISAAC"
    SURNAME: "GUI2024"
    CONFIA: "YES"
 tags:
    poc: "true"
EOF
echo "${LAMBDA_MANIFEST}" > $HOME/ack/function.yaml

kubectl apply -f $HOME/ack/function.yaml

Visualize o status das lambda criada via ACK:

kubectl get function -A

kubectl describe function $FUNCTION_NAME

Verifique se a lambda foi criada no console da AWS.

Remova a lambda via ACK

kubectl delete -f $HOME/ack/function.yaml

Crie uma lambda via ArgoCD + ACK

Crie um git repo público com o código do Kustomize que gerenciará o código ACK para criar a lambda usando o ArgoCD

Exemplo: https://github.com/aeciopires/poc-ack-argocd

Crie o seguinte arquivo com o seguinte código:

export GIT_APP_REPO="https://github.com/aeciopires/poc-ack-argocd"

read -r -d '' LAMBDA_ARGOCD_MANIFEST <<EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: aecio-ack-lambda-hello-word
spec:
  destination:
    namespace: default
    server: 'https://kubernetes.default.svc'
  source:
    path: kustomize/testing/lambda/aecio-ack-lambda-hello-word/
    repoURL: '$GIT_APP_REPO'
    targetRevision: HEAD
  project: default
  syncPolicy:
    syncOptions:
      - CreateNamespace=true
EOF
echo "${LAMBDA_ARGOCD_MANIFEST}" > $HOME/ack/argocd_app_lambda.yaml

Acesse a interface web do ArgoCD em: https://localhost:8443/applications.

Clique em New App. Clique em Edit YAML e cole o YAML do arquivo $HOME/ack/argocd_app_lambda.yaml.

Depois clique em Sync.

Verifique se a lambda foi criada no console da AWS.

Considerações finais

A tecnologia, documentação, funcionalidades e exemplos estão em desenvolvimento e em status alpha. Para algumas coisas, você encontra instruções de forma fácil, mas para outras não e aí tem que escovar bits mesmo…

Isso tende a melhorar de acordo com o desenvolvimento e evolução da tecnologia.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *