AWS Cloudshell一键更换EC2实例Elastic IP(含运营商IP)
普通实例更换IP:
#!/bin/bash
# 确保脚本以错误退出方式运行
set -e
# 用户需要配置的变量
# 请输入您的目标实例 ID
INSTANCE_ID="i-080a5478b1443441d" # 替换为您的 EC2 实例 ID
# 获取当前关联的 Elastic IP 的 Allocation ID
CURRENT_EIP_ALLOC_ID=$(aws ec2 describe-addresses --filters "Name=instance-id,Values=$INSTANCE_ID" --query "Addresses[0].AllocationId" --output text)
if [ "$CURRENT_EIP_ALLOC_ID" != "None" ]; then
echo "当前实例 ($INSTANCE_ID) 关联的 Elastic IP Allocation ID: $CURRENT_EIP_ALLOC_ID"
echo "正在释放当前的 Elastic IP..."
aws ec2 release-address --allocation-id $CURRENT_EIP_ALLOC_ID
echo "当前的 Elastic IP 已释放。"
else
echo "实例 ($INSTANCE_ID) 没有关联的 Elastic IP。"
fi
# 分配新的 Elastic IP
echo "正在分配新的 Elastic IP..."
NEW_EIP_ALLOC_ID=$(aws ec2 allocate-address --domain vpc --query "AllocationId" --output text)
NEW_EIP_PUBLIC_IP=$(aws ec2 describe-addresses --allocation-ids $NEW_EIP_ALLOC_ID --query "Addresses[0].PublicIp" --output text)
echo "新的 Elastic IP Allocation ID: $NEW_EIP_ALLOC_ID"
echo "新的 Elastic IP Public IP: $NEW_EIP_PUBLIC_IP"
# 关联新的 Elastic IP 到实例
echo "正在将新的 Elastic IP 关联到实例 ($INSTANCE_ID)..."
aws ec2 associate-address --instance-id "$INSTANCE_ID" --allocation-id "$NEW_EIP_ALLOC_ID"
echo "新的 Elastic IP 已成功关联到实例 ($INSTANCE_ID)。"
echo "新的 Public IP: $NEW_EIP_PUBLIC_IP"
以下是更换运营商IP(Wavelength)
#!/bin/bash
# ------------------------------
# 脚本:按回车分配并释放 EIP,直到实例拿到一个未用过的运营商 IP 并记录时间
# 如果用户输入的 Network Border Group 末尾带 'a'(如 us-east-1-foe-wlz-1a),则自动去除尾部的 'a'
# ------------------------------
set -e
# 1. 启动时输入实例 ID 和网络边界组
read -p "请输入 EC2 实例 ID(例如 i-04cdc286300c68ee8): " INSTANCE_ID
read -p "请输入 Network Border Group(例如 us-east-1-wl1-atl-wlz-1 或 us-east-1-foe-wlz-1a): " NETWORK_BORDER_GROUP
# 1.1 如果 Network Border Group 末尾带 'a',去除之
if [[ "$NETWORK_BORDER_GROUP" == *a ]]; then
echo "检测到 Network Border Group 末尾为 'a',准备移除尾部 'a'…"
NETWORK_BORDER_GROUP="${NETWORK_BORDER_GROUP%a}"
echo "更新后的 Network Border Group → $NETWORK_BORDER_GROUP"
fi
# 2. 从 Network Border Group 提取区域(Region)
# 例如 NETWORK_BORDER_GROUP="us-east-1-wl1-atl-wlz-1",则 REGION="us-east-1"
REGION=$(echo "$NETWORK_BORDER_GROUP" | cut -d- -f1-3)
# 3. 历史记录文件(时间 + IP),文件名 ip.txt
USED_IP_FILE="ip.txt"
touch "$USED_IP_FILE"
echo
echo "======================================"
echo "脚本已启动。每次按回车键尝试换一个未用过的运营商 IP。"
echo "要退出,请按 Ctrl+C"
echo "======================================"
echo
# 4. 主循环:每次回车触发一次“换 IP”流程
while true; do
read -p "按回车键开始换 IP…"
# 内层循环:直到拿到一个全新的 IP 才跳出
while true; do
# ---- A. 如果实例已有 EIP,先解除关联并释放 ----
CURRENT_ALLOC_ID=$(aws ec2 describe-addresses \
--filters "Name=instance-id,Values=$INSTANCE_ID" \
--query "Addresses[0].AllocationId" \
--output text --region "$REGION")
if [ "$CURRENT_ALLOC_ID" != "None" ]; then
echo "检测到已有 EIP:$CURRENT_ALLOC_ID,正在解除关联并释放…"
ASSOC_ID=$(aws ec2 describe-addresses \
--filters "Name=instance-id,Values=$INSTANCE_ID" \
--query "Addresses[0].AssociationId" \
--output text --region "$REGION")
aws ec2 disassociate-address --association-id "$ASSOC_ID" --region "$REGION"
aws ec2 release-address \
--allocation-id "$CURRENT_ALLOC_ID" \
--network-border-group "$NETWORK_BORDER_GROUP" \
--region "$REGION"
fi
# ---- B. 分配新的 EIP 并关联到实例 ----
echo "分配新的 EIP..."
NEW_ALLOC_ID=$(aws ec2 allocate-address \
--domain vpc \
--network-border-group "$NETWORK_BORDER_GROUP" \
--query "AllocationId" \
--output text \
--region "$REGION")
aws ec2 associate-address \
--instance-id "$INSTANCE_ID" \
--allocation-id "$NEW_ALLOC_ID" \
--region "$REGION" >/dev/null
# ---- C. 立即解除关联并释放这个 EIP ----
ASSOC_NEW=$(aws ec2 describe-addresses \
--allocation-ids "$NEW_ALLOC_ID" \
--query "Addresses[0].AssociationId" \
--output text --region "$REGION")
echo "解除关联并释放 EIP ($NEW_ALLOC_ID → AssocId: $ASSOC_NEW)…"
aws ec2 disassociate-address --association-id "$ASSOC_NEW" --region "$REGION"
aws ec2 release-address \
--allocation-id "$NEW_ALLOC_ID" \
--network-border-group "$NETWORK_BORDER_GROUP" \
--region "$REGION"
# ---- D. 从实例的 Public DNS 提取当前 IP ----
PUBLIC_DNS=$(aws ec2 describe-instances \
--instance-ids "$INSTANCE_ID" \
--query "Reservations[0].Instances[0].PublicDnsName" \
--output text --region "$REGION")
if [ -n "$PUBLIC_DNS" ] && [ "$PUBLIC_DNS" != "None" ]; then
DNS_HOST="${PUBLIC_DNS%%.*}" # ec2-155-146-100-87
IP_PART="${DNS_HOST#ec2-}" # 155-146-100-87
INSTANCE_IP="${IP_PART//-/\.}" # 155.146.100.87
else
# 如果 DNS 拿不到,就直接取 PublicIpAddress
INSTANCE_IP=$(aws ec2 describe-instances \
--instance-ids "$INSTANCE_ID" \
--query "Reservations[0].Instances[0].PublicIpAddress" \
--output text --region "$REGION")
fi
echo "当前实例运营商 IP → $INSTANCE_IP"
# ---- E. 去重检查:如果已记录,继续循环;否则记录并跳出 ----
if grep -Fq "$INSTANCE_IP" "$USED_IP_FILE"; then
echo ">> IP $INSTANCE_IP 已用过,重试一次…"
echo
continue
fi
# 记录时间戳和新 IP
TIMESTAMP=$(date "+%Y-%m-%dT%H:%M:%S%z")
echo "$TIMESTAMP $INSTANCE_IP" >> "$USED_IP_FILE"
echo "✅ 已记录:$TIMESTAMP $INSTANCE_IP"
echo
# 拿到全新 IP,结束内层循环
break
done
done
合并脚本:
#!/bin/bash
# 确保脚本以错误退出方式运行
set -e
# 历史记录文件(时间 + IP),文件名 ip.txt
USED_IP_FILE="ip.txt"
touch "$USED_IP_FILE"
# ------------------------------
# 脚本:合并“普通实例按回车换 EIP”与“Wavelength 实例按回车循环换运营商 IP”两种模式
# 并统一将每次新分配到的 IP(包括普通实例的 Elastic IP 和 Wavelength 实例的运营商 IP)
# 记录到 ip.txt,格式:
#
# 使用说明:
# 1. 运行脚本后,按提示输入 EC2 实例 ID
# 2. 若直接按回车跳过 Network Border Group 输入,则进入“普通实例按回车换 EIP”模式
# 3. 若输入 Network Border Group(如 us-east-1-wl1-atl-wlz-1 或 us-east-1-foe-wlz-1a),则进入“Wavelength 实例循环换运营商 IP”模式
# ------------------------------
# 普通实例按回车换 EIP 的函数
simple_swap_interactive() {
local INSTANCE_ID="$1"
echo
echo "======================================"
echo "普通实例按回车换 EIP 模式"
echo "每次按回车,都将:"
echo " • 释放当前 Elastic IP(若存在)"
echo " • 分配并关联一个新的 Elastic IP"
echo " • 记录时间戳和新 IP 到 $USED_IP_FILE"
echo "要退出,请按 Ctrl+C"
echo "======================================"
echo
while true; do
read -p "按回车键开始换 EIP…"
# 获取并释放当前关联的 Elastic IP(若有)
CURRENT_ALLOC_ID=$(aws ec2 describe-addresses \
--filters "Name=instance-id,Values=$INSTANCE_ID" \
--query "Addresses[0].AllocationId" \
--output text)
if [ "$CURRENT_ALLOC_ID" != "None" ]; then
echo "检测到已有 EIP:$CURRENT_ALLOC_ID,正在释放…"
aws ec2 release-address --allocation-id "$CURRENT_ALLOC_ID"
echo "已释放:$CURRENT_ALLOC_ID"
else
echo "当前实例 ($INSTANCE_ID) 没有关联的 Elastic IP。"
fi
# 分配新的 Elastic IP 并关联
echo "分配新的 Elastic IP…"
NEW_ALLOC_ID=$(aws ec2 allocate-address --domain vpc --query "AllocationId" --output text)
NEW_PUBLIC_IP=$(aws ec2 describe-addresses --allocation-ids "$NEW_ALLOC_ID" --query "Addresses[0].PublicIp" --output text)
aws ec2 associate-address --instance-id "$INSTANCE_ID" --allocation-id "$NEW_ALLOC_ID"
echo "✅ 完成:实例 ($INSTANCE_ID) 的新 Elastic IP → $NEW_PUBLIC_IP"
# 记录时间戳和新 IP
TIMESTAMP=$(date "+%Y-%m-%dT%H:%M:%S%z")
echo "$TIMESTAMP $NEW_PUBLIC_IP" >> "$USED_IP_FILE"
echo "已记录到 $USED_IP_FILE:$TIMESTAMP $NEW_PUBLIC_IP"
echo
done
}
# Wavelength 实例按回车循环换运营商 IP 的函数
interactive_swap() {
local INSTANCE_ID="$1"
local NETWORK_BORDER_GROUP="$2"
# 如果 Network Border Group 末尾带 'a',去除之
if [[ "$NETWORK_BORDER_GROUP" == *a ]]; then
echo "检测到 Network Border Group 末尾为 'a',准备移除尾部 'a'…"
NETWORK_BORDER_GROUP="${NETWORK_BORDER_GROUP%a}"
echo "更新后的 Network Border Group → $NETWORK_BORDER_GROUP"
fi
# 从 Network Border Group 提取区域(Region),如 us-east-1
REGION=$(echo "$NETWORK_BORDER_GROUP" | cut -d- -f1-3)
echo
echo "======================================"
echo "Wavelength 实例循环换运营商 IP 模式"
echo "每次按回车,脚本会:"
echo " 1. 解除并释放当前 EIP(若有)"
echo " 2. 在指定 Network Border Group 下分配临时 EIP 并释放"
echo " 3. 获取新的运营商 IP,检查去重并记录"
echo "要退出,请按 Ctrl+C"
echo "======================================"
echo
# 主循环:每次回车触发一次换 IP 流程
while true; do
read -p "按回车键开始换运营商 IP…"
# 内层循环:直到拿到一个未记录过的运营商 IP
while true; do
# A. 如果实例已有 EIP,先解除关联并释放
CURRENT_ALLOC_ID=$(aws ec2 describe-addresses \
--filters "Name=instance-id,Values=$INSTANCE_ID" \
--query "Addresses[0].AllocationId" \
--output text \
--region "$REGION")
if [ "$CURRENT_ALLOC_ID" != "None" ]; then
echo "检测到已有 EIP:$CURRENT_ALLOC_ID,正在解除关联并释放…"
ASSOC_ID=$(aws ec2 describe-addresses \
--filters "Name=instance-id,Values=$INSTANCE_ID" \
--query "Addresses[0].AssociationId" \
--output text \
--region "$REGION")
aws ec2 disassociate-address --association-id "$ASSOC_ID" --region "$REGION"
aws ec2 release-address --allocation-id "$CURRENT_ALLOC_ID" \
--network-border-group "$NETWORK_BORDER_GROUP" --region "$REGION"
fi
# B. 分配新的临时 EIP 并关联到实例
echo "分配新的临时 EIP…"
NEW_ALLOC_ID=$(aws ec2 allocate-address \
--domain vpc \
--network-border-group "$NETWORK_BORDER_GROUP" \
--query "AllocationId" \
--output text --region "$REGION")
aws ec2 associate-address --instance-id "$INSTANCE_ID" \
--allocation-id "$NEW_ALLOC_ID" --region "$REGION" >/dev/null
# C. 立即解除关联并释放这个 EIP
ASSOC_NEW=$(aws ec2 describe-addresses \
--allocation-ids "$NEW_ALLOC_ID" \
--query "Addresses[0].AssociationId" \
--output text --region "$REGION")
echo "解除关联并释放临时 EIP ($NEW_ALLOC_ID → AssocId: $ASSOC_NEW)…"
aws ec2 disassociate-address --association-id "$ASSOC_NEW" --region "$REGION"
aws ec2 release-address --allocation-id "$NEW_ALLOC_ID" \
--network-border-group "$NETWORK_BORDER_GROUP" --region "$REGION"
# D. 获取当前实例的 Public DNS 或 PublicIpAddress,提取运营商 IP
PUBLIC_DNS=$(aws ec2 describe-instances \
--instance-ids "$INSTANCE_ID" \
--query "Reservations[0].Instances[0].PublicDnsName" \
--output text --region "$REGION")
if [ -n "$PUBLIC_DNS" ] && [ "$PUBLIC_DNS" != "None" ]; then
DNS_HOST="${PUBLIC_DNS%%.*}"
IP_PART="${DNS_HOST#ec2-}"
INSTANCE_IP="${IP_PART//-/\.}"
else
INSTANCE_IP=$(aws ec2 describe-instances \
--instance-ids "$INSTANCE_ID" \
--query "Reservations[0].Instances[0].PublicIpAddress" \
--output text --region "$REGION")
fi
echo "当前实例运营商 IP → $INSTANCE_IP"
# E. 去重检查:如果已记录,继续循环;否则记录并跳出
if grep -Fq "$INSTANCE_IP" "$USED_IP_FILE"; then
echo ">> IP $INSTANCE_IP 已用过,重试一次…"
echo
continue
fi
# 记录时间戳和新 IP
TIMESTAMP=$(date "+%Y-%m-%dT%H:%M:%S%z")
echo "$TIMESTAMP $INSTANCE_IP" >> "$USED_IP_FILE"
echo "✅ 已记录到 $USED_IP_FILE:$TIMESTAMP $INSTANCE_IP"
echo
# 拿到全新 IP,结束内层循环
break
done
done
}
# ----------- 主流程 -----------
# 1. 输入实例 ID
read -p "请输入 EC2 实例 ID(例如 i-04cdc286300c68ee8): " INSTANCE_ID
# 2. 输入 Network Border Group(留空则执行普通实例模式)
read -p "请输入 Network Border Group(留空执行普通实例模式): " NETWORK_BORDER_GROUP
if [ -z "$NETWORK_BORDER_GROUP" ]; then
simple_swap_interactive "$INSTANCE_ID"
else
interactive_swap "$INSTANCE_ID" "$NETWORK_BORDER_GROUP"
fi