DEV Community

Cover image for Essential DevOps Tools for macOS
Joaquin Menchaca
Joaquin Menchaca

Posted on

Essential DevOps Tools for macOS

This guide walks through installing popular tools for cloud provisioning and container management on macOS. While many may not realize it, macOS traces its roots back to NeXTSTEP and is built on the Mach-derived XNU kernel. The Darwin userland provides a BSD-based Unix environment with familiar POSIX tools, along with macOS-specific additions such as the launchd init and service management system. This Unix heritage is what allows many Linux-focused cloud and container tools to run reliably on macOS with minimal differences.

The challenge arises when scripts written for Linux-based cloud environments are run on macOS. Because macOS ships with BSD-flavored utilities, such as grep, sed, and awk, scripts that work correctly on Linux may behave differently or fail entirely. To address this, this guide not only covers installing cloud provisioning tools like Terraform and Kubernetes tooling, but also walks through installing a common set of command-line tools so that scripts behave consistently across both Linux and macOS.

The Tools

This is an overview of the tools.

Cloud Provisioning

  • Terraform [terraform]: tool for provisioning cloud infrastructure.
  • AWS CLI [aws]: tool to interact with Amazon Web Services
  • okta-aws-cli [okta-aws-cli]: allows you to get temporary IAM credentials using Okta as the Identity provider.

Kubernetes

  • Kubernetes CLI [kubectl]: command line tool for interacting with Kubernetes control plan
  • Helm [helm]: Tool for configuring, installing, and distributing Kubernetes applications.
  • [Kustomize] [kustomize]: tool to configure Kubernetes application through patching.
  • Helmfile [helmfile]: is a declarative spec for deploying helm charts that allows you to template helm chart values as well integrate patching support
  • Krew [kubectl krew]: is a plugin system for Kubernetes

Java

Beyond compiling languages and running java programs, there are tools to manage certificate, keytool, and a useful tool for managing tar archives: jar.

  • Correto OpenJDK [java, javac, jar, keytool]: Corretto is an OpenJDK distribution that is supported on many platforms.

Others

  • Vault [vault]: Allow securing, storing, and controlling access to secrets artifacts: tokens, passwords, certificates, and encryption keys.

The Package System

You can install Homebrew with the following commands:

# Install XCode command line tools
xcode-select --install

# Install Homebrew
URL="https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh"
/bin/bash -c "$(curl -fsSL $URL)"
Enter fullscreen mode Exit fullscreen mode

The Common Core Commands

These commands represent a common set of tools I use across Linux and Windows MSYS2 environments. They include GNU utilities such as bash, find, gawk, grep, and sed, along with commonly used tools like bc, curl, git, jq, and zsh. While macOS includes some of these commands by default, they are often BSD variants with different behavior or significantly older versions that lack features commonly relied upon in scripts.

# Install common core commands (GNU + bc, curl, jq, zsh) 
brew install \
  autoconf \
  bash \
  bc \
  binutils \
  coreutils \
  curl \
  diffutils \
  ed \
  findutils \
  flex \
  gawk \
  git \
  gnu-indent \
  gnu-sed \
  gnu-tar \
  gnu-which \
  gpatch \
  grep \
  gzip \
  jq \
  less \
  m4 \
  make \
  nano \
  screen \
  watch \
  wdiff \
  wget \
  zip \
  zsh
Enter fullscreen mode Exit fullscreen mode

The Available Shells

You can run this to make these updated shells available to your environment by appending them to /etc/shells.

echo "$(brew --prefix)/bin/bash" | sudo tee -a /etc/shells
echo "$(brew --prefix)/bin/zsh" | sudo tee -a /etc/shells
Enter fullscreen mode Exit fullscreen mode

The Default Shell

While I prefer Zsh as my default interactive shell due to its rich prompt and plugin ecosystem provided by Oh My Zsh!, all of my scripts are written and tested using GNU Bash for portability and consistency.

You can change your default shell using one of the commands below to the shell of your choice:

chsh -s $(brew --prefix)/bin/bash
chsh -s $(brew --prefix)/bin/zsh
Enter fullscreen mode Exit fullscreen mode

When running shell scripts, use env command for your shebang to select the shell from your path, rather than override with a dinosaur version of the shell provided by the system.

Examples:

  • Bash shebang line: #!/usr/bin/env bash
  • Zsh shebang line: #!/usr/bin/env zsh

The Paths

These new GNU commands and other Keg-only commands will not be available for scripts, so they need to be added to the PATH.

You will want to add this below to your startup scripts, like .bash_profile or .zshrc for macOS.

update_homebrew_path() {
  local BREW_PREFIX
  local GNU_PATHS
  local KEG_PATHS
  local COMBINED_PATHS
  local DEDUPE_SCRIPT

  if ! command -v brew &>/dev/null; then return fi

  BREW_PREFIX="$(brew --prefix)"
  GNU_PATHS=$(printf "%s:" "${BREW_PREFIX}/opt/"*"/libexec/gnubin")
  KEG_PATHS=$(
    brew info --installed --json=v1 \
      | jq -r 'map(select(.keg_only == true)) | .[].name' \
      | while read -r PKG; do
          if [[ -d "${BREW_PREFIX}/opt/${PKG}/bin" ]]; then
            printf "%s:" "${BREW_PREFIX}/opt/${PKG}/bin"
          fi
        done
  )

  COMBINED_PATHS="${GNU_PATHS}${KEG_PATHS}"
  DEDUPE_SCRIPT='print join ":", grep { ! $seen{$_}++ } split /:/, shift'

  perl -e "${DEDUPE_SCRIPT}" "${COMBINED_PATHS}" | sed 's/^://; s/:$//'
}

NEW_PATHS="$(update_homebrew_path)"
export PATH="${NEW_PATHS}:${PATH}"
Enter fullscreen mode Exit fullscreen mode

The Installation

Now that we have the basic consistent core commands available, we can install cloud provisioning (terraform), Kubernetes tools (kubectl, helm, helmfile, kustomize), Corretto (java, jar, keytool), and other tools (vault, jq).

# install AWS CLI
brew install awscli
brew install okta-aws-cli

# install packages
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
brew install hashicorp/tap/vault
brew install kubernetes-cli  # kubectl
brew install helm # helm

# Java
brew tap homebrew/cask-versions
brew install --cask corretto17

# Helmfile and Kustomize
brew install kustomize
brew install helmfile

# Other
brew install jq
Enter fullscreen mode Exit fullscreen mode

Verification

You can verify the tool installations with the following.

# verify installations
terraform --version
vault --version
kubectl version --client
helm version
kustomize version
helmfile --version
java --version
aws --version
okta-aws-cli --version
Enter fullscreen mode Exit fullscreen mode

Plugins

Both helm and Kubernetes can extend their functionality through a plugin. Here’s how you can get some popular plugins for these tools.

Helm Plugins

Helm has a few plugins that you can install, as shown below. I highly recommend the helm-diff, as this allows you to see what resources you will modify before installing or upgrading the the application.

helm plugin install https://github.com/databus23/helm-diff
helm plugin install https://github.com/aslafy-z/helm-git
helm plugin install https://github.com/hypnoglow/helm-s3.git
helm plugin install https://github.com/jkroepke/helm-secrets
Enter fullscreen mode Exit fullscreen mode

Kubernetes Plugin Engine

Kubernetes has a plugin system with Kubernetes Krew. You can use this script below to install Krew.

#!/usr/bin/env bash

main() {
  install_krew
  # Add this in your startup scripts 
  export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"
}

install_krew() {
  TEMP_DIR=$(mktemp -d)
  pushd $TEMP_DIR
  OS="$(uname | tr '[:upper:]' '[:lower:]')"
  ARCH="$(
    uname -m \
    | sed -e 's/x86_64/amd64/' \
          -e 's/\(arm\)\(64\)\?.*/\1\2/' \
          -e 's/aarch64$/arm64/'
  )"
  KREW="krew-${OS}_${ARCH}"
  PKG="/${KREW}.tar.gz"
  URL_PATH="kubernetes-sigs/krew/releases/latest/download/$PKG"
  URL="https://github.com/$URL_PATH"
  curl -fsSLO "$URL"
  tar zxvf "${KREW}.tar.gz"
  ./"${KREW}" install krew
  popd
  rm -rf TEMP_DIR
}

main
Enter fullscreen mode Exit fullscreen mode

Extra: The Package Manifest

Homebrew supports using a package manifest that list all the packages in a single file called Brewfile. Create a file named Brewfile with the following contents:

# Common Core Commands
brew 'autoconf'
brew 'bash'
brew 'bc'
brew 'binutils'
brew 'coreutils'
brew 'curl'
brew 'diffutils'
brew 'ed'
brew 'findutils'
brew 'flex'
brew 'gawk'
brew 'git'
brew 'gnu-indent'
brew 'gnu-sed'
brew 'gnu-tar'
brew 'gnu-which'
brew 'gpatch'
brew 'grep'
brew 'gzip'
brew 'jq'
brew 'less'
brew 'm4'
brew 'make'
brew 'nano'
brew 'screen'
brew 'watch'
brew 'wdiff'
brew 'wget'
brew 'zip'
brew 'zsh'

# AWS Tools
brew 'awscli'
brew 'okta-aws-cli'
# Hashicorp
tap 'hashicorp/tap'
brew 'hashicorp/tap/terraform'
brew 'hashicorp/tap/vault'
# Kubernetes
brew 'kubernetes-cli'
brew 'helm'
brew 'kustomize'
brew 'helmfile'
# Java
tap 'homebrew/cask-versions'
cask 'corretto17'
# Other
brew 'jq'
Enter fullscreen mode Exit fullscreen mode

When ready, you can install packages listed in the Brewfile with the following command:

brew bundle --verbose
Enter fullscreen mode Exit fullscreen mode

Remember to set up the PATH correctly to include the paths to GNU and Keg-only commands. Also, update the available shells in /etc/shells to that your new version of zsh and bash are available.

Top comments (0)