| name | modern-automation-patterns |
| description | Modern DevOps and CI/CD automation patterns with containers and cloud (2025) |
🚨 CRITICAL GUIDELINES
Windows File Path Requirements
MANDATORY: Always Use Backslashes on Windows for File Paths
When using Edit or Write tools on Windows, you MUST use backslashes (\) in file paths, NOT forward slashes (/).
Examples:
- ❌ WRONG:
D:/repos/project/file.tsx
- ✅ CORRECT:
D:\repos\project\file.tsx
This applies to:
- Edit tool file_path parameter
- Write tool file_path parameter
- All file operations on Windows systems
Documentation Guidelines
NEVER create new documentation files unless explicitly requested by the user.
- Priority: Update existing README.md files rather than creating new documentation
- Repository cleanliness: Keep repository root clean - only README.md unless user requests otherwise
- Style: Documentation should be concise, direct, and professional - avoid AI-generated tone
- User preference: Only create additional .md files when user specifically asks for documentation
Modern Automation Patterns (2025)
Overview
Production-ready patterns for DevOps automation, CI/CD pipelines, and cloud-native operations following 2025 industry standards.
Container-Aware Scripting
Docker/Kubernetes Detection
#!/usr/bin/env bash
set -euo pipefail
detect_container() {
if [[ -f /.dockerenv ]]; then
echo "docker"
elif grep -q docker /proc/1/cgroup 2>/dev/null; then
echo "docker"
elif [[ -n "${KUBERNETES_SERVICE_HOST:-}" ]]; then
echo "kubernetes"
else
echo "host"
fi
}
readonly CONTAINER_ENV=$(detect_container)
case "$CONTAINER_ENV" in
docker|kubernetes)
DATA_DIR="/data"
CONFIG_DIR="/config"
;;
host)
DATA_DIR="/var/lib/app"
CONFIG_DIR="/etc/app"
;;
esac
Minimal Container Scripts
#!/bin/sh
set -eu
if [ $$ -eq 1 ]; then
trap 'kill -TERM $child 2>/dev/null' TERM INT
/app/main &
child=$!
wait "$child"
else
exec /app/main
fi
Health Check Scripts
#!/usr/bin/env bash
set -euo pipefail
check_health() {
local timeout=1
if ! pgrep -f "myapp" > /dev/null; then
echo "Process not running" >&2
return 1
fi
if ! timeout "$timeout" curl -sf http://localhost:8080/health > /dev/null; then
echo "Health endpoint failed" >&2
return 1
fi
if [[ ! -f /app/ready ]]; then
echo "Not ready" >&2
return 1
fi
return 0
}
check_health
CI/CD Pipeline Patterns
GitHub Actions Helper
#!/usr/bin/env bash
set -euo pipefail
is_github_actions() {
[[ "${GITHUB_ACTIONS:-false}" == "true" ]]
}
gh_output() {
local name="$1"
local value="$2"
if is_github_actions; then
echo "${name}=${value}" >> "$GITHUB_OUTPUT"
fi
}
gh_error() {
if is_github_actions; then
echo "::error::$*"
else
echo "ERROR: $*" >&2
fi
}
gh_warning() {
if is_github_actions; then
echo "::warning::$*"
else
echo "WARN: $*" >&2
fi
}
gh_notice() {
if is_github_actions; then
echo
}
() {
is_github_actions;
>>
}
gh_notice
build_result=$(make build 2>&1)
gh_output
gh_summary
Azure DevOps Helper
#!/usr/bin/env bash
set -euo pipefail
is_azure_devops() {
[[ -n "${TF_BUILD:-}" ]]
}
azdo_output() {
local name="$1"
local value="$2"
if is_azure_devops; then
echo "##vso[task.setvariable variable=$name]$value"
fi
}
azdo_error() {
if is_azure_devops; then
echo "##vso[task.logissue type=error]$*"
else
echo "ERROR: $*" >&2
fi
}
azdo_warning() {
if is_azure_devops; then
echo "##vso[task.logissue type=warning]$*"
else
echo "WARN: $*" >&2
fi
}
azdo_section_start() {
is_azure_devops && echo "##[section]$*"
}
azdo_section_end() {
is_azure_devops &&
}
azdo_section_start
test_result=$(npm )
azdo_output
azdo_section_end
Multi-Platform CI Detection
#!/usr/bin/env bash
set -euo pipefail
detect_ci() {
if [[ "${GITHUB_ACTIONS:-false}" == "true" ]]; then
echo "github"
elif [[ -n "${TF_BUILD:-}" ]]; then
echo "azuredevops"
elif [[ -n "${GITLAB_CI:-}" ]]; then
echo "gitlab"
elif [[ -n "${CIRCLECI:-}" ]]; then
echo "circleci"
elif [[ -n "${JENKINS_URL:-}" ]]; then
echo "jenkins"
else
echo "local"
fi
}
ci_output() {
local name="$1"
local value="$2"
local ci_env
ci_env=$(detect_ci)
case "$ci_env" in
github)
>>
;;
azuredevops)
;;
gitlab)
>> ci_output.env
;;
*)
;;
}
() {
ci_env
ci_env=$(detect_ci)
github)
;;
azuredevops)
;;
*)
>&2
;;
}
Cloud Provider Patterns
AWS Helper Functions
#!/usr/bin/env bash
set -euo pipefail
require_aws() {
if ! command -v aws &> /dev/null; then
echo "Error: AWS CLI not installed" >&2
exit 1
fi
}
get_aws_account_id() {
aws sts get-caller-identity --query Account --output text
}
get_aws_secret() {
local secret_name="$1"
aws secretsmanager get-secret-value \
--secret-id "$secret_name" \
--query SecretString \
--output text
}
s3_upload_retry() {
local file="$1"
local s3_path="$2"
local max_attempts=3
local attempt=1
while ((attempt <= max_attempts)); do
if aws s3 cp "$file" "$s3_path"; then
return 0
fi
echo "Upload failed (attempt $attempt/$max_attempts)" >&2
((attempt++))
$((attempt * ))
1
}
() {
role_arn=
session_name=
credentials
credentials=$(aws sts assume-role \
--role-arn \
--role-session-name \
--query Credentials \
--output json)
AWS_ACCESS_KEY_ID=$( | jq -r .AccessKeyId)
AWS_SECRET_ACCESS_KEY=$( | jq -r .SecretAccessKey)
AWS_SESSION_TOKEN=$( | jq -r .SessionToken)
}
Azure Helper Functions
#!/usr/bin/env bash
set -euo pipefail
require_az() {
if ! command -v az &> /dev/null; then
echo "Error: Azure CLI not installed" >&2
exit 1
fi
}
get_az_subscription_id() {
az account show --query id --output tsv
}
get_keyvault_secret() {
local vault_name="$1"
local secret_name="$2"
az keyvault secret show \
--vault-name "$vault_name" \
--name "$secret_name" \
--query value \
--output tsv
}
az_blob_upload() {
local file="$1"
local container="$2"
local blob_name="${3:-$(basename "$file")}"
az storage blob upload \
--file "$file" \
--container-name "$container" \
--name "$blob_name" \
--overwrite
}
() {
resource=
curl -sf -H Metadata: \
\
| jq -r .access_token
}
Parallel Processing Patterns
GNU Parallel
#!/usr/bin/env bash
set -euo pipefail
if command -v parallel &> /dev/null; then
export -f process_file
find data/ -name "*.json" | parallel -j 4 process_file {}
else
max_jobs=4
job_count=0
for file in data/*.json; do
process_file "$file" &
((job_count++))
if ((job_count >= max_jobs)); then
wait -n
((job_count--))
fi
done
wait
fi
Job Pool Pattern
#!/usr/bin/env bash
set -euo pipefail
job_pool_init() {
readonly MAX_JOBS="${1:-4}"
JOB_POOL_PIDS=()
}
job_pool_run() {
while ((${#JOB_POOL_PIDS[@]} >= MAX_JOBS)); do
job_pool_wait_any
done
"$@" &
JOB_POOL_PIDS+=($!)
}
job_pool_wait_any() {
if ((${#JOB_POOL_PIDS[@]} > 0)); then
local pid
wait -n
for i in "${!JOB_POOL_PIDS[@]}"; do
if ! kill -0 "${JOB_POOL_PIDS[$i]}" 2>/dev/null; then
unset 'JOB_POOL_PIDS[$i]'
fi
done
JOB_POOL_PIDS=("${JOB_POOL_PIDS[@]}")
fi
}
job_pool_wait_all() {
wait
JOB_POOL_PIDS=()
}
job_pool_init 4
file data/*.txt;
job_pool_run process_file
job_pool_wait_all
Deployment Patterns
Blue-Green Deployment
#!/usr/bin/env bash
set -euo pipefail
deploy_blue_green() {
local new_version="$1"
local health_check_url="$2"
echo "Starting blue-green deployment: $new_version"
echo "Deploying to green environment..."
deploy_to_environment "green" "$new_version"
echo "Running health checks..."
if ! check_health "$health_check_url"; then
echo "Health check failed, rolling back" >&2
return 1
fi
echo "Switching traffic to green..."
switch_traffic "green"
echo "Deployment complete. Blue environment kept for rollback."
}
check_health() {
local url="$1"
local max_attempts=30
local attempt=1
while ((attempt <= max_attempts)); do
if curl -sf > /dev/null;
0
2
((attempt++))
1
}
Canary Deployment
#!/usr/bin/env bash
set -euo pipefail
deploy_canary() {
local new_version="$1"
local stages=(5 10 25 50 100)
echo "Starting canary deployment: $new_version"
for percentage in "${stages[@]}"; do
echo "Rolling out to $percentage% of traffic..."
update_traffic_split "$percentage" "$new_version"
echo "Monitoring for 5 minutes..."
if ! monitor_metrics 300; then
echo "Issues detected, rolling back" >&2
update_traffic_split 0 "$new_version"
return 1
fi
echo "Stage $percentage% successful"
done
echo "Canary deployment complete"
}
monitor_metrics() {
local duration="$1"
local end_time=$((SECONDS + duration))
((SECONDS < end_time));
error_rate
error_rate=$(get_error_rate)
((error_rate > ));
>&2
1
10
0
}
Logging and Monitoring
Structured Logging
#!/usr/bin/env bash
set -euo pipefail
log_json() {
local level="$1"
local message="$2"
shift 2
local timestamp
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
local json
json=$(jq -n \
--arg timestamp "$timestamp" \
--arg level "$level" \
--arg message "$message" \
--arg script "$SCRIPT_NAME" \
--argjson context "$(echo "$@" | jq -Rs .)" \
'{
timestamp: $timestamp,
level: $level,
message: $message,
script: $script,
context: $context
}')
echo "$json" >&2
}
log_info() { log_json "INFO" "$@"; }
log_error() { log_json "ERROR" "$@"; }
log_warn() { log_json "WARN" "$@"; }
log_info "Processing file" "file=/data/input.txt"
Resources
Modern automation requires cloud-native patterns, container awareness, and robust CI/CD integration. These patterns ensure production-ready deployments in 2025.