professional-service/scripts
Stanislav Kopp a16d6dcadb
All checks were successful
Professional Services CI / Secret Scanner (TruffleHog) (pull_request) Successful in 1m37s
Professional Services CI / Pre-Commit Hooks (pull_request) Successful in 5m34s
chore: use proper example usernames
2026-04-16 15:32:37 +02:00
..
check-stackit-ip.sh feat(scripts): add ip-check, project-inventory and vault-migration scripts 2026-04-16 15:20:06 +02:00
create-kubeconfig-multiple-projects.sh chore(scripts): add safeguard for provided scripts 2026-04-16 10:41:26 +02:00
delete-unused-volumes.sh chore(scripts): add safeguard for provided scripts 2026-04-16 10:41:26 +02:00
list-project-resources.sh feat(scripts): add ip-check, project-inventory and vault-migration scripts 2026-04-16 15:20:06 +02:00
README.md chore: use proper example usernames 2026-04-16 15:32:37 +02:00
ske-show-versions.sh chore(docs): improve contents section 2026-04-16 11:47:42 +02:00
smctl.sh Add more scripts plus README for each script 2026-04-16 11:23:06 +02:00
vault-migrate.sh chore: use proper example usernames 2026-04-16 15:32:37 +02:00

Scripts

Helper scripts for working with STACKIT services.

Warning: These scripts can perform destructive or wide-reaching operations against your STACKIT account (e.g. deleting volumes, overwriting kubeconfigs, writing secrets). Review each script and understand what it does before running it.

Overview

Script Purpose Required tools
check-stackit-ip.sh Check whether a given IP address belongs to STACKIT's public IP ranges. stackit, jq, grepcidr
create-kubeconfig-multiple-projects.sh Generate kubeconfig entries for every SKE cluster across one or more STACKIT projects. stackit, yq
delete-unused-volumes.sh Delete all STACKIT volumes whose status is AVAILABLE (i.e. not attached). stackit, yq
list-project-resources.sh Render a Markdown inventory of resources (DNS, SKE, databases, storage, …) for one or more STACKIT projects. stackit, jq
ske-show-versions.sh Print overview of SKE cluster Kubernetes versions and nodepool image versions, marking deprecated versions. stackit (>= 0.59.0), jq, awk
smctl.sh Unified CLI wrapper around HashiCorp Vault for the STACKIT Secret Manager (KV v2), think kubectl for secrets vault, jq
vault-migrate.sh Migrate secrets between two Vault instances using the KV v2 API (supports userpass and LDAP for source). vault, jq

check-stackit-ip.sh

Looks up the STACKIT public IP ranges (via stackit curl https://iaas.api.eu01.stackit.cloud/v1/networks/public-ip-ranges) and tells you whether a given IP falls inside any of them. Useful to verify whether a public-facing address actually originates from STACKIT.

Exits 0 if the IP is found, 1 otherwise.

Example

# Check a single IP
./check-stackit-ip.sh 45.129.40.1

Sample output:

Fetching STACKIT IP ranges...
Found: 45.129.40.1 is in the range 45.129.40.0/22

create-kubeconfig-multiple-projects.sh

Logs in to STACKIT, iterates over a hard-coded list of project IDs, lists all SKE clusters in each project and writes a 60-day kubeconfig for every cluster into a single kubeconfig file.

Edit the projects=( ... ) array near the bottom of the script before running.

Flags

  • -f, --filepath <path> — destination kubeconfig path (default: $HOME/.kube/config).
  • -h, --help — show usage.

Examples

# Write to default ~/.kube/config (will prompt before overwriting)
./create-kubeconfig-multiple-projects.sh

# Write to a custom location
./create-kubeconfig-multiple-projects.sh -f ~/.kube/stackit-config

delete-unused-volumes.sh

Lists all STACKIT volumes in the currently configured project and deletes those with status AVAILABLE.

Set DRY_RUN=1 at the top of the script to preview the deletions without executing them.

Examples

# Make sure the right project is selected
stackit config set --project-id <project-id>

# Preview what would be deleted (edit DRY_RUN=1 in the script first)
./delete-unused-volumes.sh

# Actually delete unused volumes
./delete-unused-volumes.sh

ske-show-versions.sh

Prints a tabular overview of SKE clusters across the project IDs configured in the projectid variable. For each nodepool it shows the Kubernetes version and the Flatcar machine image version, annotated with supported or the expirationDate for deprecated versions. Rows containing any deprecated version are highlighted in red.

The script enforces a minimum STACKIT CLI version (0.59.0).

Edit the projectid="..." variable (space-separated list) before running.

Example

./ske-show-versions.sh

Sample output:

CLUSTER NAME         SKE VERSION                    NODEPOOL             FLATCAR VERSION                MACHINE TYPE    PROJECT ID
------------         -----------                    --------             ---------------                ------------    ----------
prod-cluster         1.30.4 (supported)             default              4081.2.0 (supported)           c1.4            xxxxxxxx-...
legacy-cluster       1.27.9 (exp. 2026-05-01)       default              3815.2.5 (exp. 2026-03-15)     c1.2            yyyyyyyy-...

Summary:
Total clusters: 2

smctl.sh

Wrapper around the vault CLI to works with secrets in STACKIT Secrets Manager, think about it as kubectl but for secrets.

Required environment variables

Variable Description
SM_USERNAME STACKIT Secret Manager username
SM_PASSWORD STACKIT Secret Manager password
SM_ID KV secrets engine mount path (your secret manager instance ID)

Commands

Command Description
get <vault_path> <key> Print the value of a single key.
get <vault_path> all Print all keys as key: value.
get <vault_path> all-export Print all keys as export key=value (suitable for eval/source).
put <vault_path> <key> [value] Write/update a key. Reads from stdin if no value is given. Existing keys at the path are preserved.
list List all secret paths under the mount.
list <vault_path> List all keys at a specific path.
help Show usage.

Examples

export SM_USERNAME='my-user'
export SM_PASSWORD='my-pass'
export SM_ID='sm-xxxxxxxx'

# List all paths
./smctl.sh list

# List keys at a path
./smctl.sh list postgresql

# Read a single value
./smctl.sh get postgresql db_password

# Dump everything at a path
./smctl.sh get postgresql all

# Load all secrets at a path into the current shell
eval "$(./smctl.sh get postgresql all-export)"

# Write a value directly
./smctl.sh put postgresql db_password 'super-secret'

# Write a value from a file (e.g. a full .env)
./smctl.sh put terraform secret-env < .env

list-project-resources.sh

Iterates over the listable STACKIT services (DNS, Git, Load Balancers, SKE etc.) and prints a Markdown report containing one section per project with a table per resource type. Intended to be redirected into a .md file.

Project IDs are passed as arguments — at least one is required.

Example

# Single project
./list-project-resources.sh xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx > project-inventory.md

# Multiple projects in one report
./list-project-resources.sh \
  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy \
  > inventory.md

Sample output (excerpt):

## Project: my-prod-project (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)

**SKE Clusters:**
|name|status|...|
|---|---|---|
|prod-cluster|HEALTHY|...|

**Public IPs:**
N/A

last update: Thu, 16-Apr-2026 14:42:11 CEST

vault-migrate.sh

Migrates secrets between two KV v2-compatible secret backends, typically from a HashiCorp Vault instance into STACKIT Secrets Manager, or from one STACKIT Secrets Manager instance to another (both expose the Vault KV v2 API). Source authentication can be userpass or ldap (LDAP triggers an interactive password prompt); the target always uses userpass. Recursively walks all paths under the source mount unless MIGRATE_PATHS is set.

Flags

  • -d, --dry-run — show what would be migrated without writing.
  • -v, --verbose — verbose progress output.
  • -s, --skip-existing — skip secrets that already exist in the target.
  • --debug — debug output (implies --verbose).
  • -h, --help — show usage.

Required environment variables

Variable Description
SOURCE_VAULT_ADDR Source Vault address (e.g. https://vault.example.com).
SOURCE_SM_ID Source KV mount path.
SOURCE_AUTH_METHOD userpass (default) or ldap.
SOURCE_SM_USERNAME Source username — required when SOURCE_AUTH_METHOD=userpass.
SOURCE_SM_PASSWORD Source password — required when SOURCE_AUTH_METHOD=userpass.
SOURCE_LDAP_USERNAME LDAP username — required when SOURCE_AUTH_METHOD=ldap.
TARGET_VAULT_ADDR Target Vault address.
TARGET_SM_USERNAME Target Vault username (always userpass).
TARGET_SM_PASSWORD Target Vault password.
TARGET_SM_ID Target KV mount path.
MIGRATE_PATHS Optional space-separated list of paths to migrate (default: all).

Examples

# Common target setup
export TARGET_VAULT_ADDR="https://prod.sm.eu01.stackit.cloud"
export TARGET_SM_USERNAME="target-user"
export TARGET_SM_PASSWORD='<your-target-password>'
export TARGET_SM_ID="sm-target-xxxx"

# 1) Dry run — migrate everything from a userpass source
export SOURCE_VAULT_ADDR="https://old.vault.example.com"
export SOURCE_SM_ID="sm-source-xxxx"
export SOURCE_AUTH_METHOD="userpass"
export SOURCE_SM_USERNAME="source-user"
export SOURCE_SM_PASSWORD='<your-source-password>'
./vault-migrate.sh --dry-run --verbose

# 2) Migrate from an LDAP source (will prompt for password)
export SOURCE_AUTH_METHOD="ldap"
export SOURCE_LDAP_USERNAME="myuser"
./vault-migrate.sh

# 3) Migrate only selected paths, skipping ones that already exist
export MIGRATE_PATHS="postgresql redis terraform"
./vault-migrate.sh --skip-existing --verbose