This repository walks through implementing GitOps with GitHub Actions and ArgoCD to deploy applications via helm to EKS
For this demo, we will create the EKS cluster using EKSCTL. Before that, some housekeeping
export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
export AWS_REGION=$(aws ec2 describe-availability-zones --query 'AvailabilityZones[0].[RegionName]' --output text)
export AZ1=$(aws ec2 describe-availability-zones --query 'AvailabilityZones[0].ZoneName' --region $AWS_REGION --output text)
export AZ2=$(aws ec2 describe-availability-zones --query 'AvailabilityZones[1].ZoneName' --region $AWS_REGION --output text)
export AZ3=$(aws ec2 describe-availability-zones --query 'AvailabilityZones[2].ZoneName' --region $AWS_REGION --output text)
export K8S_VERSION=1.25
If you do not have eksctl installed, install it.
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv -v /tmp/eksctl /usr/local/bin
eksctl completion bash >> ~/.bash_completion
. /etc/profile.d/bash_completion.sh
. ~/.bash_completion
Create a CMK for the EKS cluster to use when encrypting your Kubernetes secrets:
aws kms create-alias --alias-name alias/eksworkshop --target-key-id $(aws kms create-key --query KeyMetadata.Arn --output text)
Let’s retrieve the ARN of the CMK to input into the create cluster command.
export KEY_ARN=$(aws kms describe-key --key-id alias/eksworkshop --query KeyMetadata.Arn --output text)
We set the KEY_ARN environment variable to make it easier to refer to the KMS key later.
Now, let’s save the KEY_ARN environment variable into the bash_profile
echo "export KEY_ARN=${KEY_ARN}" | tee -a ~/.bash_profile
Now let's create the cluster
eksctl create cluster -f config/cluster.yaml
Test the cluster
kubectl get nodes
# if we see our 3 nodes, we know we have authenticated correctly
Update kubeconfig file to interact with the EKS cluster
aws eks update-kubeconfig --name eks-gitops --region ${AWS_REGION}
... In the same region, and call it eks-gitops-argocd
. This is because the files/ configurations in this demo use that name.
Use IAM roles for GitHub Actions to connect to Amazon ECR. Follow this blog to set it up.
Use the contents below for .github/main.yml
# This is a basic workflow to help you get started with Actions
name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
AWS_REGION : "<AWS_REGION>"
# Permission can be added at job level or workflow level
permissions:
id-token: write # This is required for requesting the JWT
contents: write # This is required for actions/checkout
jobs:
build:
name: Building and Pushing the Image
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: configure aws credentials
uses: aws-actions/[email protected]
with:
role-to-assume: arn:aws:iam::<AWS_ACCOUNT_ID>:role/<IAM_ROLE_NAME>
role-session-name: GitHub_to_AWS_via_FederatedOIDC
aws-region: ${{ env.AWS_REGION }}
# Hello from AWS: WhoAmI
- name: Sts GetCallerIdentity
run: |
aws sts get-caller-identity
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: eks-gitops-argocd
run: |
# Build a docker container and push it to ECR
git_hash=$(git rev-parse --short "$GITHUB_SHA")
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:${GITHUB_REF##*/}-$git_hash docker/.
echo "Pushing image to ECR..."
docker push $ECR_REGISTRY/$ECR_REPOSITORY:${GITHUB_REF##*/}-$git_hash
echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:${GITHUB_REF##*/}-$git_hash"
- name: Update Version
run: |
git_hash=$(git rev-parse --short "$GITHUB_SHA")
version=$(cat ./charts/helm-example/values.yaml | grep version: | awk '{print $2}')
sed -i "s/$version/${GITHUB_REF##*/}-$git_hash/" ./charts/helm-example/values.yaml
- name: Commit and push changes
uses: devops-infra/[email protected]
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
commit_message: Version updated
Install helm
curl -sSL https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
helm version --short
Install ArgoCD
helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd argo/argo-cd --set server.service.type=LoadBalancer
Access the UI which is sitting behing an ELB. To get the password:
kubectl get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo
Connect to the Repo -> Add/Create an application
sudo curl --silent --location -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/download/v2.4.7/argocd-linux-amd64
sudo chmod +x /usr/local/bin/argocd
export ARGOCD_SERVER=`kubectl get svc argocd-server -o json | jq --raw-output '.status.loadBalancer.ingress[0].hostname'`
export ARGO_PWD=`kubectl get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d`
argocd login $ARGOCD_SERVER --username admin --password $ARGO_PWD --insecure
Add ECR helm repo
argocd repo add XXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com --type helm --name eks-gitops-argocd --enable-oci --username AWS --password $(aws ecr get-login-password --region us-west-2)