Skip to content

Instantly share code, notes, and snippets.

@swinton
Last active June 20, 2022 10:17
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save swinton/a7e1eeb43d6e37b692d651c089611761 to your computer and use it in GitHub Desktop.
Save swinton/a7e1eeb43d6e37b692d651c089611761 to your computer and use it in GitHub Desktop.
# eks.yml
on:
pull_request:
push:
branches: # array of glob patterns matching against refs/heads. Optional; defaults to all
- master # triggers on pushes that contain changes in master
name: Build and Deploy to EKS
env:
AWS_REGION: us-east-2
CONTAINER_IMAGE: example-eks:${{ github.sha }}
jobs:
build-and-deploy:
name: Build and deploy
runs-on: ubuntu-latest
steps:
- name: Context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: |
echo "$GITHUB_CONTEXT"
- name: Checkout
uses: actions/checkout@master
- name: Setup AWS
env:
AWS_HOME: ${{ runner.temp }}/.aws
AWS_CONFIG_FILE: ${{ runner.temp }}/.aws/config
AWS_SHARED_CREDENTIALS_FILE: ${{ runner.temp }}/.aws/credentials
run: |
# Set the PATH to include our binaries
mkdir -p "${HOME}/.local/bin"
export PATH="${HOME}/.local/bin:${PATH}"
echo "::set-env name=PATH,::${PATH}"
# Configure AWS
mkdir -p "${AWS_HOME}"
echo "::set-env name=AWS_CONFIG_FILE,::${AWS_CONFIG_FILE}"
echo "::set-env name=AWS_SHARED_CREDENTIALS_FILE,::${AWS_SHARED_CREDENTIALS_FILE}"
aws configure set default.region $AWS_REGION
aws configure set default.output json
aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }}
aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# Validate AWS credentials
aws sts get-caller-identity
- name: Setup ECR
run: |
# Login to AWS ECR
$( aws ecr get-login --region $AWS_REGION --no-include-email )
- name: Setup Kube Context
env:
KUBECONFIG: ${{ runner.temp }}/.kube/config
run: |
# Setup AWS IAM Authenticator for Kubernetes
cd $( mktemp -d )
curl -o aws-iam-authenticator --location https://amazon-eks.s3-us-west-2.amazonaws.com/1.13.7/2019-06-11/bin/linux/amd64/aws-iam-authenticator
chmod +x ./aws-iam-authenticator
mv ./aws-iam-authenticator "${HOME}/.local/bin"
aws-iam-authenticator help
# Setup kustomize
cd $( mktemp -d )
curl -o kustomize --location https://github.com/kubernetes-sigs/kustomize/releases/download/v3.1.0/kustomize_3.1.0_linux_amd64
chmod u+x ./kustomize
mv ./kustomize "${HOME}/.local/bin"
# Setup Kube Config
mkdir -p "${RUNNER_TEMP}/.kube"
echo "::set-env name=KUBECONFIG,::${KUBECONFIG}"
echo "${{ secrets.KUBE_CONFIG_DATA }}" | base64 --decode > "${KUBECONFIG}"
- name: Build, tag, and save the image
run: |
# Build and tag the image
docker build \
-t $CONTAINER_IMAGE \
-t $GITHUB_REPOSITORY:$GITHUB_SHA \
-t ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.$AWS_REGION.amazonaws.com/$CONTAINER_IMAGE .
# Save the image so it can be uploaded as an artifact
docker save $CONTAINER_IMAGE | gzip > ./example-eks.tar.gz
du -h ./example-eks.tar.gz
- name: Upload artifact
uses: actions/upload-artifact@v1.0.0
with:
name: docker-image
path: ./example-eks.tar.gz
- name: Deploy
if: github.ref == 'refs/heads/master'
run: |
# Push image to AWS ECR
docker push ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.$AWS_REGION.amazonaws.com/$CONTAINER_IMAGE
# Apply configuration to cluster
export KUBECONFIG="${RUNNER_TEMP}/.kube/config"
kustomize edit set image ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.$AWS_REGION.amazonaws.com/example-eks:${GITHUB_SHA}
kustomize build . | kubectl apply -f -
# Verify deployment
kubectl rollout status deployment/aws-example-octodex
# List Public IP of cluster
kubectl get services -o wide

Notes

Capturing some notes on how I setup my EKS cluster, as it took several attempts 😂 😳

AWS Account

I created a brand new AWS account, since I kept bumping up against limits when using the existing GitHub / Professional Services AWS. I made a careful note of:

  1. My AWS account id
  2. My Access Key ID
  3. My Secret Access Key

Despite what the AWS docs say, I used my root credentials throughout this demo, just to save time.

Installation

I followed the steps from this guide to setup aws, eksctl, kubectl, and aws-iam-authenticator locally:

pip install awscli --upgrade --user

# Install eksctl
brew tap weaveworks/tap

brew install weaveworks/tap/eksctl

eksctl version
# [ℹ]  version.Info{BuiltAt:"", GitCommit:"", GitTag:"0.3.1"}

Install and Configure kubectl for Amazon EKS

It's already done for us on macOS (thanks homebrew 🙇):

which kubectl
# /usr/local/bin/kubectl

which aws-iam-authenticator
# /Users/swinton/go/bin/aws-iam-authenticator

Create Your Amazon EKS Cluster and Worker Nodes

Despite what this page says, I just did:

eksctl create cluster

I had to wait for my AWS account to be approved before this would work. It seems the account has to be approved for each region separately, when it comes to EKS.

Eventually I was able to get an EKS cluster running in the us-east-2 region.

Access the cluster

# When your cluster is ready, test that your kubectl configuration is correct
kubectl get svc

Generate a kube config

CLUSTER_NAME=fabulous-monster-1565378541  # this was generated from the above eksctl create cluster command 
AWS_DEFAULT_REGION=us-east-2
aws eks update-kubeconfig --name $CLUSTER_NAME --region $AWS_DEFAULT_REGION

This generates a ~/.kube/config file, I then base64-encoded the contents of this file and saved it as a secret, KUBE_CONFIG_DATA, in my @bbq-beets repo.

cat ~/.kube/config | base64 | pbcopy

ECR

For the demo to work, it's also necessary to create an ECR registry, in the same AWS region as the EKS cluster (us-east-2 in my case). I did this directly via the AWS console:

Screen Shot 2019-08-13 at 2 57 08 PM

I then updated the kube config.yml to match this ECR registry URI.

Secrets

The following secrets are also required:

Screen Shot 2019-08-13 at 2 49 11 PM

  1. AWS_ACCOUNT_ID: My AWS account id
  2. AWS_ACCESS_KEY_ID: My Access Key ID for my root account, which isn't the ideal, but it works
  3. AWS_SECRET_ACCESS_KEY: My Secret Access Key for my root account, which isn't the ideal, but it works
  4. AWS_ECR_PASSWORD: The password for ECR, obtained via aws ecr get-login --region $AWS_REGION --no-include-email
  5. KUBE_CONFIG_DATA: From the above, cat ~/.kube/config | base64 | pbcopy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment