all-devops¶
The complete multi-cloud toolkit: the shared base plus AWS CLI v2 with Session Manager and the Google Cloud CLI with the GKE auth plugin.
ghcr.io/jinalshah/devops/images/all-devops
When to use it¶
-
Great for
- Platform teams running AWS and Google Cloud
- CI pipelines that deploy to more than one cloud
- A single "does everything" workstation image
-
Consider instead
- AWS only: aws-devops
- Google Cloud only: gcp-devops
The shared base is most of the size, so the single-cloud images are only a few hundred MB smaller.
| Image | Compressed download | Unpacked (amd64) |
|---|---|---|
| all-devops | ~1.6 GB | ~5.0 GB |
| aws-devops | ~1.55 GB | ~4.6 GB |
| gcp-devops | ~1.5 GB | ~4.6 GB |
What's inside¶
flowchart LR
B["Shared base<br/>IaC, Kubernetes, Ansible, Trivy,<br/>AI CLIs, DB clients"] --> A["all-devops"]
W["AWS layer<br/>AWS CLI v2, Session Manager,<br/>boto3, cfn-lint, s3cmd"] --> A
G["GCP layer<br/>gcloud, gsutil, bq,<br/>gke-gcloud-auth-plugin"] --> A
classDef base fill:#0891b2,stroke:#0e7490,color:#fff
classDef aws fill:#ea7a0c,stroke:#c2410c,color:#fff
classDef gcp fill:#2563eb,stroke:#1d4ed8,color:#fff
classDef all fill:#059669,stroke:#047857,color:#fff
class B base
class W aws
class G gcp
class A all
-
AWS
AWS CLI v2, Session Manager plugin, and the Python packages boto3, cfn-lint, s3cmd, requests, pytest, bs4 and lxml
-
Google Cloud
gcloud(withbeta),gsutil,bq,docker-credential-gcr,gke-gcloud-auth-plugin -
Infrastructure as code
Terraform (via tfswitch), Terragrunt, TFLint, Packer
-
Kubernetes
kubectl, Helm 3, k9s (
kubectl kustomizeis built in) -
Automation & security
Ansible, ansible-lint, pre-commit, Task, Trivy
-
AI coding agents
Claude Code (
claude), OpenAI Codex CLI (codex), GitHub Copilot CLI (copilot), Google Antigravity CLI (agy) -
Database clients
mongosh(MongoDB 8.0),psql17,mysql8.4 -
Languages & utilities
Python 3.14, Node.js LTS, Git,
gh, jq, ghorg, Zensical, dig, nmap, ncat, curl, zsh, bash, fish
The four AI CLIs are all agentic terminal assistants: they read and edit files and run commands, interactively or non-interactively. See the AI CLI setup guide for sign-in.
Search the full list in the tool explorer.
Quick start¶
docker run -it --rm \
-v "$PWD":/srv -w /srv \
-v ~/.ssh:/root/.ssh:ro \
-v ~/.aws:/root/.aws \
-v ~/.config/gcloud:/root/.config/gcloud \
-v ~/.kube:/root/.kube \
ghcr.io/jinalshah/devops/images/all-devops:latest
Then check both clouds from inside the container:
Common tasks¶
docker run --rm \
-v "$PWD":/srv -w /srv \
-v ~/.aws:/root/.aws \
-v ~/.config/gcloud:/root/.config/gcloud \
ghcr.io/jinalshah/devops/images/all-devops:latest \
bash -c 'terraform -chdir=aws init && terraform -chdir=aws plan &&
terraform -chdir=gcp init && terraform -chdir=gcp plan'
The Google provider uses Application Default Credentials, so run gcloud auth application-default login on the host first.
docker run --rm \
-v "$PWD":/srv -w /srv \
-v ~/.aws:/root/.aws \
-v ~/.config/gcloud:/root/.config/gcloud \
-v ~/.kube:/root/.kube \
ghcr.io/jinalshah/devops/images/all-devops:latest \
bash -c '
aws eks update-kubeconfig --region eu-west-2 --name my-eks
helm upgrade --install myapp ./charts/myapp -n production
gcloud container clusters get-credentials my-gke --region europe-west2
helm upgrade --install myapp ./charts/myapp -n production
'
Each update-kubeconfig / get-credentials switches the current context, so each helm call targets the cluster just added. The GKE context uses gke-gcloud-auth-plugin, which is why ~/.config/gcloud must be mounted whenever you use it.
In CI¶
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
container:
image: ghcr.io/jinalshah/devops/images/all-devops:1.0.abc1234
steps:
- uses: actions/checkout@v7
- uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: eu-west-2
- uses: google-github-actions/auth@v3
with:
workload_identity_provider: ${{ secrets.GCP_WIF_PROVIDER }}
service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
- run: terraform -chdir=terraform/aws init && terraform -chdir=terraform/aws apply -auto-approve
- run: terraform -chdir=terraform/gcp init && terraform -chdir=terraform/gcp apply -auto-approve
deploy:
image: registry.gitlab.com/jinal-shah/devops/images/all-devops:1.0.abc1234
variables:
GOOGLE_APPLICATION_CREDENTIALS: /tmp/gcp-key.json
before_script:
- echo "$GCP_SA_KEY" | base64 -d > /tmp/gcp-key.json
- gcloud auth activate-service-account --key-file=/tmp/gcp-key.json
script:
- terraform -chdir=terraform/aws init && terraform -chdir=terraform/aws apply -auto-approve
- terraform -chdir=terraform/gcp init && terraform -chdir=terraform/gcp apply -auto-approve
GOOGLE_APPLICATION_CREDENTIALS is read by Terraform and client libraries; gcloud itself needs the explicit activate-service-account. AWS keys come from masked CI/CD variables.
Pinning
1.0.<sha> tags are per-commit and refreshed by scheduled rebuilds. Pin by digest when you need byte-for-byte reproducibility; see Tags and version pinning.
Troubleshooting¶
Unable to locate credentials from the AWS CLI
Check the mount and the identity:
docker run --rm -v ~/.aws:/root/.aws \
ghcr.io/jinalshah/devops/images/all-devops:latest \
bash -c 'ls -la /root/.aws && aws sts get-caller-identity'
With IAM Identity Center (SSO) profiles, run aws sso login --profile <name> first (on the host, or in the container with --use-device-code); the token cache lives in ~/.aws/sso/cache, so it is shared through the mount.
gcloud or GKE authentication errors
Sign in on the host (or inside the container with the mount in place), then verify:
Pull is slow
The image is about 1.6 GB compressed. Use GHCR, keep one pinned tag across pipeline jobs so persistent (self-hosted) runners can reuse cached layers, and remove old images with docker image prune. GitHub-hosted runners start clean, so they pull the image on every job.
Next steps¶
- Authentication guide: AWS, Google Cloud and AI CLI credentials
- Workflows & patterns: multi-cloud pipelines
- Architecture: how the layers fit together