Why Argo CD?
Application definitions, configurations, and environments should be declarative and version controlled. Application deployment and lifecycle management should be automated, auditable, and easy to understand.
Source: https://argoproj.github.io/cd/
Repositório Terraform (Infraestrutura).
Deploy Amazon EKS
- Definir variáveis no terraform (variables.tfvars):
## PROJECT BASE
cluster_name = "pegasus"
environment = "staging"
project = "devops"
aws_region = "us-east-2"
az1 = "us-east-2a"
az2 = "us-east-2b"
## CLUSTER OPTIONS
k8s_version = "1.27"
endpoint_private_access = true
instance_type = [
"t3a.medium"
]
desired_size = "1"
min_size = "1"
max_size = "1"
enabled_cluster_log_types = [
"api", "audit", "authenticator", "controllerManager", "scheduler"
]
addon_cni_version = "v1.13.4-eksbuild.1"
addon_coredns_version = "v1.10.1-eksbuild.2"
addon_kubeproxy_version = "v1.27.3-eksbuild.2"
addon_csi_version = "v1.21.0-eksbuild.1"
## INGRESS OPTIONS (ISTIO NLB)
nlb_ingress_internal = "false"
enable_cross_zone_lb = "true"
nlb_ingress_type = "network"
proxy_protocol_v2 = "false"
grafana_virtual_service_host = "grafana.pauloponciano.pro"
kiali_virtual_service_host = "kiali.pauloponciano.pro"
jaeger_virtual_service_host = "jaeger.pauloponciano.pro"
argocd_virtual_service_host = "argocd.pauloponciano.pro"
## KARPENTER OPTIONS
karpenter_instance_class = [
"m5",
"c5",
"t3a"
]
karpenter_instance_size = [
"large",
"2xlarge"
]
karpenter_capacity_type = [
"spot"
]
karpenter_azs = [
"us-east-2a",
"us-east-2b"
]
## NETWORKING
vpc_cidr = "10.0.0.0/16"
public_subnet_az1_cidr = "10.0.16.0/20"
public_subnet_az2_cidr = "10.0.32.0/20"
private_subnet_az1_cidr = "10.0.48.0/20"
private_subnet_az2_cidr = "10.0.64.0/20"
- Caso utilize um certificado existente do ACM, informe o 'arn' em nlb.tf:
resource "aws_lb_listener" "ingress_443" {
load_balancer_arn = aws_lb.istio_ingress.arn
port = "443"
#protocol = "TCP"
protocol = "TLS"
certificate_arn = "arn:aws:acm:us-east-2:accountid:certificate/925700c8-03d1-4f4a-890a-249ffe2fa4f0"
alpn_policy = "HTTP2Preferred"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.https.arn
}
}
Caso não utilize certificado nenhum, altere esse bloco para:
resource "aws_lb_listener" "ingress_443" {
load_balancer_arn = aws_lb.istio_ingress.arn
port = "443"
protocol = "TCP"
#protocol = "TLS"
#certificate_arn = "arn:aws:acm:us-east-2:accountid:certificate/925700c8-03d1-4f4a-890a-249ffe2fa4f0"
#alpn_policy = "HTTP2Preferred"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.https.arn
}
}
- Executar terraform:
terraform init
terraform plan --var-file variables.tfvars
terraform apply --var-file variables.tfvars
- Conecte no cluster EKS:
aws eks --region us-east-2 update-kubeconfig --name pegasus
- Aqui eu utilizei um domínio público já criado no Route 53 e inseri os registros abaixo apontando para o CNAME do NLB que foi criado pelo terraform:
ArgoCD
Na execução da stack terraform dos passos anteriores, já foi feito deploy do Argo e vamos fazer alguns ajustes para acessá-lo e seguir na configuração.
- Ajuste para terminação do SSL no NLB — Alterando o* ConfigMap* do ArgoCD server:
kubectl edit cm argocd-cmd-params-cm -n argocd
Inserir:
data:
server.insecure: 'true'
Reciclar:
kubectl rollout restart deployment argocd-server -n argocd
- Acessando o Argo UI:
- Recuperar senha inicial para login:
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
- Já conectado no Argo, adicionamos um novo repositório em 'Settings'. Esse respositório é onde o Argo fica olhando e buscando por diferenças/alterações nos manifestos do kubernetes:
O repositório sendo privado no GitHub, é necessário gerar um PAT (Personal Access Token) para informar como password no momento de conectar através do Argo.
- Ainda em *'Settings', criamos um novo 'Project':
- Em 'Applications', criamos uma nova especificando o path dos manifestos kubernetes dentro do repositório adicionado anteriormente:
Rapidamente o Argo entrega a aplicação rodando no cluster, pois o Auto sync já está habilitado neste caso:
- O app de exemplo está acessível:
GitHub / Actions
Agora na prática, vamos alcançar o cenário ilustrado abaixo utilizando GitHub Actions:
No repositório do app e manifestos existe essa estrutura:
.github/workflows/cd.yaml
name: CD
on:
push:
branches: [main]
paths-ignore:
- 'k8s/**'
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v3
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: build image and push to docker hub
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: paulofponciano/webgo:${{ github.sha }}, paulofponciano/webgo:latest
deploy:
name: Deploy
runs-on: ubuntu-latest
needs: build
steps:
- name: checkout
uses: actions/checkout@v3
- name: kustomize
uses: imranismail/setup-kustomize@v2
with:
kustomize-version: v5.1.1
- name: update k8s
run: |
cd k8s
kustomize edit set image webgo=paulofponciano/webgo:${{ github.sha }}
cat kustomization.yaml
- name: commit
run: |
git config --local user.email "paulofponciano@gmail.com"
git config --local user.name "Paulo"
git commit -am "actions change image tag"
- name: push
uses: ad-m/github-push-action@master
Basicamente sempre que houver um push na branch 'main' que não seja no diretório de manifestos 'k8s', as actions serão executadas. Isso significa que alguém está querendo entregar uma alteração na aplicação e uma nova imagem docker será criada para essa entrega.
- No GitHub precisamos configurar os Repository secrets necessários para push da imagem no Docker Hub e Workflow permissions:
Settings > Actions > General > Workflow permissions
- Acionando as actions através de uma alteração no 'main.go':
Push para o repositório:
- Actions:
O resultdo do job chamado de ‘Build’, é o push de uma nova imagem no docker hub. Os parâmetros para o build da imagem estão no Dockerfile.
No job chamado de 'Deploy', é atualizado o manifesto kustomization.yaml para inserir a nova tag da imagem docker (usando o sha), é assim que o Argo vai saber que houve uma alteração e que é necessário um Sync:
- name: kustomize
uses: imranismail/setup-kustomize@v2
with:
kustomize-version: v5.1.1
- name: update k8s
run: |
cd k8s
kustomize edit set image webgo=paulofponciano/webgo:${{ github.sha }}
cat kustomization.yaml
- name: commit
run: |
git config --local user.email "paulofponciano@gmail.com"
git config --local user.name "Paulo"
git commit -am "actions change image tag"
- name: push
uses: ad-m/github-push-action@master
- Sync no Argo:
- Nova versão do app:
Lembrando que nossa unica ação manual até aqui, foi realizar o push da alteração que fizemos no main.go \o/
Happy building!
Top comments (0)