My Infrastructure Tools Setup Checklist: AWS, kubectl, Terraform & More

8 min read
KubernetesAWSTerraform

Table of Contents

Intro

Every time I set up a new laptop or onboard a teammate, I go through the same ritual: install AWS CLI, kubectl, terraform, istioctl, flux, and about ten other tools. Then configure profiles, contexts, aliases, and shell completions.

After doing this four times in two years, I finally documented the complete process. This is my infrastructure tools setup checklist, covering everything from tool installation to shell configuration. It takes about 30 minutes to go from a fresh macOS install to a fully configured environment.

The key insight: use Aqua for declarative tool management, and invest time in shell configuration once to save hours later.

Tool Management with Aqua

Instead of installing tools one-by-one with Homebrew, I use Aqua, a declarative CLI version manager. Think package.json for command-line tools.

Install Aqua

1brew install aquaproj/aqua/aqua
2export PATH="$(aqua root-dir)/bin:$PATH"

Configure Tools

Create ~/.config/aqua/aqua.yaml:

1registries:
2 - type: standard
3 ref: v4.307.0
4
5packages:
6 # Kubernetes ecosystem
7 - name: kubernetes/kubectl@v1.29.4
8 - name: kubernetes-sigs/kustomize@v5.4.2
9 - name: kubernetes-sigs/krew@v0.4.4
10 - name: derailed/k9s@v0.32.5
11 - name: sbstp/kubie@v0.23.0
12 - name: ahmetb/kubectx
13 - name: fluxcd/flux2@v2.4.0
14 - name: istio/istio@1.21.0
15
16 # Cloud infrastructure
17 - name: hashicorp/terraform@v1.8.5
18
19 # Utilities
20 - name: junegunn/fzf@0.48.1
21 - name: peco/peco@v0.5.11

Install everything:

1aqua install -a

Why Aqua Over Homebrew

Version locking: Homebrew auto-upgrades to latest versions. kubectl 1.32 doesn't play nice with Kubernetes 1.29 clusters. Aqua lets you pin exact versions.

Reproducibility: Share one aqua.yaml file across the team. Everyone uses identical tool versions. No more "works on my machine" from version mismatches.

Speed: Downloads prebuilt binaries from GitHub releases. No compilation. No Homebrew dependency trees.

Clean state: Everything lives in ~/.local/share/aquaproj-aqua. Delete the directory to start fresh. No scattered symlinks.

krew: kubectl Plugin Manager

krew is a plugin manager for kubectl. Install kubectl extensions like kubectl-tree, kubectl-whoami, or kubectl-neat.

Note: I installed krew with Aqua for clarity in this article, but you can also install it via Homebrew or directly from GitHub.

1# Already in aqua.yaml
2- name: kubernetes-sigs/krew@v0.4.4
3
4# Install plugins
5kubectl krew install ctx
6kubectl krew install ns
7
8# Use them
9kubectl ctx # List/switch contexts
10kubectl ns # List/switch namespaces

Like Homebrew, but for kubectl extensions.

AWS CLI and Profile Management

Install

1# Already in aqua.yaml, or:
2brew install awscli

Configure Multiple Profiles

For multi-account setups (dev/staging/production), configure profiles in ~/.aws/config:

1[profile dev]
2region = us-west-2
3output = json
4
5[profile staging]
6region = us-west-2
7output = json
8
9[profile production]
10region = us-west-2
11output = json

Use AWS SSO if available:

1aws configure sso --profile dev
2aws configure sso --profile staging
3aws configure sso --profile production

Interactive Profile Switching with Custom Alias

Install peco (already in aqua.yaml above), then create a custom alias in ~/.zshrc:

1alias awsp='export AWS_PROFILE=$(aws configure list-profiles | peco)'

Now awsp gives you an interactive menu. Visual confirmation of which profile you're using prevents production accidents.

Verify

1echo $AWS_PROFILE
2aws sts get-caller-identity

Always run get-caller-identity before infrastructure changes.

Kubernetes: kubectl, k9s, and Context Management

Install kubectl

1# Already in aqua.yaml
2- name: kubernetes/kubectl@v1.29.4

Match kubectl version to your cluster (±1 minor version). Production on 1.29? Use kubectl 1.28-1.30.

Connect to EKS Clusters

1aws eks update-kubeconfig --region us-west-2 --name dev-cluster --profile dev
2aws eks update-kubeconfig --region us-west-2 --name staging-cluster --profile staging
3aws eks update-kubeconfig --region us-west-2 --name production-cluster --profile production

Context Switching: kubie and kubectx

Instead of typing long kubectl config commands, use specialized tools.

Note: I installed kubie, kubectx, and krew with Aqua for clarity in this article, but you can also install them via Homebrew or other package managers.

kubie - Switch context for current tab only:

1kubie ctx production-cluster

kubectx - Switch context for all terminal tabs:

1kubectx production-cluster

Use kubie when you want to work in multiple contexts simultaneously (production in one tab, dev in another). Use kubectx when you want to switch everything at once.

kubectl Aliases

Add to ~/.zshrc:

1# Basic shortcuts
2alias k='kubectl'
3alias kg='kubectl get'
4alias kgp='kubectl get pods'
5alias kgs='kubectl get svc'
6alias kd='kubectl describe'
7alias kl='kubectl logs -f'
8alias kpf='kubectl port-forward'

kubectl Autocomplete

1# Add to ~/.zshrc
2source <(kubectl completion zsh)

Show Context in Prompt: kube-ps1

Even with kubectx and kubie, it's easy to forget which context you're in. Show it in your prompt.

1# Install
2git clone https://github.com/jonmosco/kube-ps1.git ~/.kube-ps1
3
4# Add to ~/.zshrc
5source ~/.kube-ps1/kube-ps1.sh
6PROMPT='%n@%m in %F{magenta}%1~%f $(kube_ps1) '

Your prompt now shows: yourname@laptop in ~/projects (⎈ production:default)

Hard to miss which context you're in.

Custom kubectl Functions

1# Restart deployment
2krestart() {
3 kubectl rollout restart deployment "$1" -n "${2:-default}"
4}
5
6# Stream logs by pod name pattern
7klogs() {
8 kubectl logs -f -n "$1" "$(kubectl get pods -n "$1" | grep "$2" | awk '{print $1}')"
9}

Usage:

1krestart api production
2klogs staging frontend

k9s: Terminal UI for Kubernetes

k9s is a terminal-based Kubernetes dashboard that's easier for interactive work. Instead of typing multiple kubectl commands to view pods, check logs, or describe resources, k9s gives you a keyboard-driven UI.

1# Already in aqua.yaml
2- name: derailed/k9s@v0.32.5
3
4# Run it
5k9s

Navigate with :pods, :svc, :deploy. Press l for logs, d for describe, s to shell into a pod. Press ? for help.

I use k9s for interactive debugging and kubectl for scripting. They complement each other.

Istio, Flux, Terraform

Istio

1# Already in aqua.yaml
2- name: istio/istio@1.21.0

Match your cluster's Istio version.

Essential commands:

1istioctl version
2istioctl analyze
3istioctl proxy-status

When debugging mysterious 503s, run istioctl analyze first. Catches 80% of common issues.

Flux

1# Already in aqua.yaml
2- name: fluxcd/flux2@v2.4.0

Essential commands:

1flux check
2flux get all
3flux reconcile kustomization <name> --with-source

Suspend Flux during load tests:

1flux suspend kustomization app-deployment
2# Run load test
3flux resume kustomization app-deployment

Terraform

1# Already in aqua.yaml
2- name: hashicorp/terraform@v1.8.5

Aliases (add to ~/.zshrc):

1alias tf='terraform'
2alias tfi='terraform init'
3alias tfp='terraform plan'
4alias tfa='terraform apply'
5alias tfd='terraform destroy'

No -auto-approve in production. Always review plans.

Workflow:

1tfi # Initialize
2tfp # Preview
3tfa # Apply (with confirmation)

Complete ~/.zshrc Configuration

1# Aqua
2export PATH="$(aqua root-dir)/bin:$PATH"
3
4# AWS Profile Switcher
5alias awsp='export AWS_PROFILE=$(aws configure list-profiles | peco)'
6
7# Kubernetes Prompt
8if [ -f ~/.kube-ps1/kube-ps1.sh ]; then
9 source ~/.kube-ps1/kube-ps1.sh
10fi
11
12setopt PROMPT_SUBST
13PROMPT='%n@%m in %F{magenta}%1~%f $(kube_ps1) '
14
15# Kubernetes Aliases
16alias k='kubectl'
17alias kg='kubectl get'
18alias kgp='kubectl get pods'
19alias kgs='kubectl get svc'
20alias kd='kubectl describe'
21alias kl='kubectl logs -f'
22alias kpf='kubectl port-forward'
23
24# Terraform Aliases
25alias tf='terraform'
26alias tfi='terraform init'
27alias tfp='terraform plan'
28alias tfa='terraform apply'
29alias tfd='terraform destroy'
30
31# kubectl Autocomplete
32source <(kubectl completion zsh)
33
34# Custom Functions
35krestart() {
36 kubectl rollout restart deployment "$1" -n "${2:-default}"
37}
38
39klogs() {
40 kubectl logs -f -n "$1" "$(kubectl get pods -n "$1" | grep "$2" | awk '{print $1}')"
41}

Reload:

1source ~/.zshrc

10-Minute Setup Checklist

1. Install Aqua

1brew install aquaproj/aqua/aqua
2export PATH="$(aqua root-dir)/bin:$PATH"

2. Create aqua.yaml

Create ~/.config/aqua/aqua.yaml with the configuration above.

3. Install all tools

1aqua install -a

4. Configure AWS

1aws configure sso --profile dev
2aws configure sso --profile staging
3aws configure sso --profile production

5. Connect to Kubernetes

1aws eks update-kubeconfig --region us-west-2 --name dev-cluster --profile dev
2aws eks update-kubeconfig --region us-west-2 --name staging-cluster --profile staging
3aws eks update-kubeconfig --region us-west-2 --name production-cluster --profile production

6. Install kube-ps1

1git clone https://github.com/jonmosco/kube-ps1.git ~/.kube-ps1

7. Configure ~/.zshrc

Copy the complete configuration above.

1source ~/.zshrc

8. Verify everything

1aws sts get-caller-identity
2kubectl version --client
3k9s version
4istioctl version
5flux check
6terraform version

Total: 10 minutes.

What This Gives You

Context awareness: awsp and kube-ps1 show exactly which AWS profile and Kubernetes context you're using. Prevents production accidents.

Speed: Aliases and functions save 5-30 seconds per command. Hundreds of commands per day = hours saved per week.

Consistency: Everyone uses the same tool versions. No version mismatch bugs.

Fast onboarding: New teammates productive in 10 minutes instead of 2 days.

Mental energy: Stop context-switching to google installation commands. Focus on actual work.

Key Lessons

Lock tool versions. Homebrew auto-upgrades break things. Aqua pins versions.

Visual indicators matter. kube-ps1 in your prompt has prevented more incidents than any monitoring system.

Document once, use forever. This checklist exists because I forgot configurations too many times.

Invest in shell config. 5 hours configuring aliases saves 200 hours over a year.

Wrapping Up

Infrastructure tools setup doesn't have to take days. With Aqua for version management, good aliases, and visual context indicators, you can reproduce a fully configured environment in 10 minutes every time.

The best infrastructure is the infrastructure you can set up consistently, quickly, and correctly every single time.

Next laptop? Follow this checklist. Same setup. Zero guesswork.

Related Articles