Last active
June 19, 2025 00:47
-
-
Save filipeandre/3f8d3147a503b6a3fda7aa46be896857 to your computer and use it in GitHub Desktop.
Clone delete stack
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Usage: | |
# ./clone_deleted_stack.sh <stack-id-or-name> [new-stack-name] [optional-role-arn] | |
set -euo pipefail | |
INPUT_ID="${1:-}" | |
NEW_STACK_NAME="${2:-}" | |
ROLE_ARN="${3:-}" | |
ARN_REGEX="^arn:aws:cloudformation:([^:]+):[^:]+:stack/([^/]+)/.+$" | |
if [[ -z "$INPUT_ID" ]]; then | |
echo "Usage: $0 <stack-id-or-name> [new-stack-name] [optional-role-arn]" | |
exit 1 | |
fi | |
# Detect if input is ARN and extract region + name | |
if [[ "$INPUT_ID" =~ $ARN_REGEX ]]; then | |
REGION="${BASH_REMATCH[1]}" | |
DELETED_STACK_NAME="${BASH_REMATCH[2]}" | |
STACK_IDENTIFIER="$INPUT_ID" | |
else | |
DELETED_STACK_NAME="$INPUT_ID" | |
REGION="${AWS_REGION:-${AWS_DEFAULT_REGION:-$(aws configure get region)}}" | |
if [[ -z "$REGION" ]]; then | |
echo "❌ Unable to determine AWS region. Please set AWS_REGION, AWS_DEFAULT_REGION, or configure a default profile." | |
exit 1 | |
fi | |
STACK_IDENTIFIER="$DELETED_STACK_NAME" | |
fi | |
NEW_STACK_NAME="${NEW_STACK_NAME:-$DELETED_STACK_NAME}" | |
PARAMS_FILE="cf_params_${DELETED_STACK_NAME}.json" | |
TEMPLATE_FILE="cf_template_${DELETED_STACK_NAME}.json" | |
# Globals for cleanup | |
TEMP_BUCKET="" | |
TEMPLATE_OBJECT="template.json" | |
cleanup() { | |
if [[ -n "$TEMP_BUCKET" ]]; then | |
echo "[+] Cleaning up temporary S3 bucket..." | |
aws s3 rm "s3://${TEMP_BUCKET}/${TEMPLATE_OBJECT}" --region "$REGION" || true | |
aws s3 rb "s3://${TEMP_BUCKET}" --region "$REGION" || true | |
fi | |
} | |
trap cleanup EXIT | |
echo "[+] Fetching deleted stack metadata:" | |
echo " Stack ID: $STACK_IDENTIFIER" | |
echo " Region: $REGION" | |
echo " New Stack: $NEW_STACK_NAME" | |
[[ -n "$ROLE_ARN" ]] && echo " Role ARN: $ROLE_ARN" | |
# Get stack info | |
stack_info=$(aws cloudformation describe-stacks \ | |
--stack-name "$STACK_IDENTIFIER" \ | |
--region "$REGION" 2>/dev/null) | |
if [[ -z "$stack_info" ]]; then | |
echo "❌ Could not retrieve stack metadata." | |
exit 1 | |
fi | |
# Extract parameters | |
echo "[+] Extracting parameters to $PARAMS_FILE..." | |
echo "$stack_info" | jq -r '.Stacks[0].Parameters' > "$PARAMS_FILE" | |
# Extract template body | |
echo "[+] Getting template body..." | |
aws cloudformation get-template \ | |
--stack-name "$STACK_IDENTIFIER" \ | |
--region "$REGION" \ | |
--query 'TemplateBody' \ | |
--output text > "$TEMPLATE_FILE" | |
# Determine if template is too large | |
MAX_DIRECT_SIZE=51200 | |
TEMPLATE_SIZE=$(wc -c <"$TEMPLATE_FILE") | |
if [[ "$TEMPLATE_SIZE" -gt "$MAX_DIRECT_SIZE" ]]; then | |
echo "[+] Template too large ($TEMPLATE_SIZE bytes). Using S3..." | |
ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text) | |
TEMP_BUCKET="cf-temp-${ACCOUNT_ID}-$(date +%s)" | |
aws s3 mb "s3://${TEMP_BUCKET}" --region "$REGION" | |
aws s3 cp "$TEMPLATE_FILE" "s3://${TEMP_BUCKET}/${TEMPLATE_OBJECT}" --region "$REGION" | |
TEMPLATE_SOURCE=(--template-url "https://s3.${REGION}.amazonaws.com/${TEMP_BUCKET}/${TEMPLATE_OBJECT}") | |
else | |
echo "[+] Template size acceptable ($TEMPLATE_SIZE bytes). Using direct body..." | |
TEMPLATE_SOURCE=(--template-body "file://$TEMPLATE_FILE") | |
fi | |
# Prepare stack creation command | |
CREATE_CMD=( | |
aws cloudformation create-stack | |
--stack-name "$NEW_STACK_NAME" | |
"${TEMPLATE_SOURCE[@]}" | |
--parameters "file://$PARAMS_FILE" | |
--capabilities CAPABILITY_NAMED_IAM | |
--region "$REGION" | |
) | |
[[ -n "$ROLE_ARN" ]] && CREATE_CMD+=(--role-arn "$ROLE_ARN") | |
# Deploy the new stack | |
echo "[+] Deploying new stack..." | |
"${CREATE_CMD[@]}" | |
echo "✅ Stack $NEW_STACK_NAME successfully deployed." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
bash <(curl -s https://gist.githubusercontent.com/filipeandre/3f8d3147a503b6a3fda7aa46be896857/raw/a1c5208bd870b3b5b5997cfd25a9ce021bd12e22/clone_deleted_stack.sh) STACK_ARN