千家信息网

常用AWS CLI Shell脚本

发表于:2025-02-04 作者:千家信息网编辑
千家信息网最后更新 2025年02月04日,您可能会用到的AWS CLI Shell脚本。主要功能有根据名字/类别管理EC2、RDS资源,创建资源时自动添加标签,创建EC2实例时可附加卷、定义用户数据文件。可用-h或--help查看支持的命令和
千家信息网最后更新 2025年02月04日常用AWS CLI Shell脚本

您可能会用到的AWS CLI Shell脚本。主要功能有根据名字/类别管理EC2、RDS资源,创建资源时自动添加标签,创建EC2实例时可附加卷、定义用户数据文件。可用-h或--help查看支持的命令和参数,GitHub源码。

支持的命令:
EC2

Usage: ./ec2.sh [command] [args ...]Commands:  create-image [instance_name] [image_name] [tags] Create an AMI from an EC2 instance  delete-image [image_name] Delete image by name  start-instance [instance_name] Start an EC2 instance  start-instances [category_name] Start EC2 instances by category  stop-instance [instance_name] Stop an EC2 instance  stop-instances [category_name] Stop EC2 instances by category  reboot-instance [instance_name] Reboot an EC2 instance  reboot-instances [category_name] Reboot EC2 instances by category  terminate-instance [instance_name] Terminate an EC2 instance  terminate-instances [category_name] Terminate EC2 instances by category  run-instance [instance_name] [image_name] [options] Launch an instance using an AMI    Options:      --device-snapshot-name One block device snapshot name      --init-file an user data file      --tags One  or more tags  create-snapshot [instance_name] [device] [snapshot_name] [tags] Creates a snapshot of the specified volume for an instance  delete-snapshot [snapshot_name] Deletes the specified snapshot  attach-volume [snapshot_name] [instance_name] [device] [tags] Create a volume from a snapshot, and then attach the volume to an instance  associate-address [instance_name] [public_ip]  Associates an Elastic IP address with an instance  replace-route [route_table_name] [nat_instance_name] [cidr] Replaces an existing route within a route table in a VPC

RDS

Usage: ./rds.sh [delete|restore] [args ...]Commands:  delete [db-instance-identifier] Delete a DB instance  restore [db-instance-identifier] [vpc-security-group-ids] Create a new DB instance from a DB snapshot

Cloud Watch

Usage: ./cloudwatch.sh [cpu] [instance_name] [sns_topic_arn]

EC2

公用方法common.sh

#!/bin/bashINSTANCE_ID_REGEX="i-\w{8,17}"IMAGE_ID_REGEX="ami-\w{8,17}"VOLUME_ID_REGEX="vol-\w{8,17}"SNAPSHOT_ID_REGEX="snap-\w{8,17}"ROUTETABLE_ID_REGEX="rtb-\w{8,17}"query_instance_id_by_name() {  instance_id=$(aws ec2 describe-instances --filter Name=tag:Name,Values="$1" Name=instance-state-name,Values=pending,running,stopped \              --query 'Reservations[0].[Instances[0].InstanceId]' | grep -o -E "$INSTANCE_ID_REGEX")  echo ${instance_id}}query_instance_ids_by_category() {  instance_ids=$(aws ec2 describe-instances --filter Name=tag:Category,Values="$1" Name=instance-state-name,Values=pending,running,stopped \               --query 'Reservations[*].[Instances[*].InstanceId]' | grep -o -E "$INSTANCE_ID_REGEX")  echo ${instance_ids}}wait_instance_ok() {  instance_id=$(aws ec2 describe-instances --filter Name=tag:Name,Values="$1" Name=instance-state-name,Values=pending,running \              --query 'Reservations[0].[Instances[0].InstanceId]' | grep -o -E "$INSTANCE_ID_REGEX")  check_instance_status ${instance_id}}check_instance_status() {  while true  do    ok_count=$(aws ec2 describe-instance-status --instance-id $1 | grep -c ok)    if [[ "$ok_count" -eq 2 ]]; then      break    else      echo "Waiting ..."      sleep 5    fi  done}describe_running_instances() {  instances=$(aws ec2 describe-instances --filter Name=instance-state-name,Values=running \            --query 'Reservations[*].Instances[*].{State:State.Name,Ip:PrivateIpAddress,InstanceId:InstanceId,Name:Tags[0].Value}')  echo ${instances}}query_image_id_by_name() {  image_id=$(aws ec2 describe-images --filter Name=name,Values="$1" --query Images[0].[ImageId] | grep -o -E "$IMAGE_ID_REGEX")  echo ${image_id}}query_volume_id_by_name() {  id=$(aws ec2 describe-volumes --filter Name=tag:Name,Values="$1" --query Volumes[0].[VolumeId] | grep -o -E "$VOLUME_ID_REGEX")  echo ${id}}query_volume_ids_by_name() {  id=$(aws ec2 describe-volumes --filter Name=tag:Name,Values="$1" --query Volumes[*].[VolumeId] | grep -o -E "$VOLUME_ID_REGEX")  echo ${id}}query_volume_id_by_instance_id_and_device() {  id=$(aws ec2 describe-volumes --filter Name=attachment.instance-id,Values="$1" Name=attachment.device,Values=$2 \     --query Volumes[0].[VolumeId] | grep -o -E "$VOLUME_ID_REGEX")  echo ${id}}query_snapshot_id_by_name() {  snapshot_id=$(aws ec2 describe-snapshots --filter Name=tag:Name,Values="$1" --query Snapshots[0].[SnapshotId] | grep -o -E "$SNAPSHOT_ID_REGEX")  echo ${snapshot_id}}query_snapshot_ids_by_image_id() {  snapshot_ids=$(aws ec2 describe-snapshots --query Snapshots[*].[SnapshotId][*] --filter Name=description,Values=*"$1"* | grep -o -E "$SNAPSHOT_ID_REGEX")  echo ${snapshot_ids}}query_route_table_id_by_name() {  id=$(aws ec2 describe-route-tables --filter Name=tag:Name,Values="$1" --query RouteTables[0].RouteTableId | grep -o -E "$ROUTETABLE_ID_REGEX")  echo ${id}}query_elb_instance_ids() {  ids=$(aws elb describe-load-balancers --load-balancer-name "$1" --query LoadBalancerDescriptions[0].[Instances[*].[InstanceId]] | grep -o -E "$INSTANCE_ID_REGEX")  echo ${ids}}create_tags_with_name() {  resource_id=$1  name=$2  tags=$3;  if [[ -z ${resource_id} ]]; then    return 1  fi  if [[ ${tags} ]]; then    echo "Add tags: ${tags}"  fi  aws ec2 create-tags --resources ${resource_id} --tags Key=Name,Value="${name}" ${tags}  echo}

EC2脚本ec2.sh

#!/bin/bash. $(dirname $0)/common.sh# 根据Instance Name创建image并添加标签create_image() {  instance_name=$1  image_name=$2  tags=$3  echo "Create image for instance ${instance_name}"  instance_id=$(query_instance_id_by_name "${instance_name}")  image_id=$(aws ec2 create-image --instance-id "${instance_id}" --name "${image_name}" --description "${image_name}" --no-reboot --query ImageId)  image_id=${image_id//\"/}  echo "ImageId: $image_id"  create_tags_with_name "${image_id}" "${image_name}" "${tags}"}# 删除AMIdelete_image() {  image_name=$1  echo "Delete image ${image_name}"  image_id=$(query_image_id_by_name "${image_name}")  echo "Image id: ${image_id}"  echo "Deregister image $image_id"  aws ec2 deregister-image --image-id "${image_id}"  snapshot_ids=$(query_snapshot_ids_by_image_id "${image_id}")  for snapshot_id in ${snapshot_ids}  do    echo "Delete snapshot ${snapshot_id}"    aws ec2 delete-snapshot --snapshot-id "${snapshot_id}"  done  echo}# 根据Name启动EC2 Instancestart_instance() {  id=$(query_instance_id_by_name "$1")  aws ec2 start-instances --instance-ids ${id}}# 根据类别启动EC2 Instancestart_instances() {  ids=$(query_instance_ids_by_category "$1")  aws ec2 start-instances --instance-ids ${ids}}# 根据Name停止EC2 Instancestop_instance() {  id=$(query_instance_id_by_name "$1")  aws ec2 stop-instances --instance-ids ${id}}# 根据类别停止EC2 Instancestop_instances() {  ids=$(query_instance_ids_by_category "$1")  aws ec2 stop-instances --instance-ids ${ids}}# 根据Name重启EC2 Instancereboot_instance() {  id=$(query_instance_id_by_name "$1")  aws ec2 reboot-instances --instance-ids ${id}}# 根据类别重启EC2 Instancereboot_instances() {  ids=$(query_instance_ids_by_category "$1")  aws ec2 reboot-instances --instance-ids ${ids}}# 根据Name终止EC2 Instanceterminate_instance() {  id=$(query_instance_id_by_name "$1")  echo "terminate instance, instance name: $1 instance id: ${id}"  aws ec2 modify-instance-attribute --instance-id "${id}" --no-disable-api-termination  aws ec2 terminate-instances --instance-ids ${id}  echo}# 根据类别终止EC2 Instanceterminate_instances() {  ids=$(query_instance_ids_by_category "$1")  echo "terminate instances, category: $1 instance-ids: ${ids}"  for id in ${ids}  do    aws ec2 modify-instance-attribute --instance-id "${id}" --no-disable-api-termination  done  aws ec2 terminate-instances --instance-ids ${ids}  echo}# 从Image创建EC2 Instance,EC2配置从JSON文件读取,可以附加一个Volume,可以使用用户数据文件,可以添加标签run_instance() {  instance_name=$1  image_name=$2  device_snapshot_name=$3  init_file=$4  tags=$5  block_device_mappings=" "  if [[ "${device_snapshot_name}" ]]; then    snapshot_id=$(query_snapshot_id_by_name "${device_snapshot_name}")    if [[ "${snapshot_id}" ]]; then      block_device_mappings="--block-device-mappings DeviceName=/dev/sdf,Ebs={SnapshotId=${snapshot_id},DeleteOnTermination=true,VolumeType=gp2}"    else      echo "Please provide a valid volume snapshot name"      exit 1    fi  fi  image_id=$(query_image_id_by_name "${image_name}")    echo "Create EC2 instance ${instance_name} from image ${image_name}(${image_id})"  if [[ "$init_file" ]]; then    instance_id=$(aws ec2 run-instances --image-id "${image_id}" ${block_device_mappings} --cli-input-json file://json/"${instance_name}".json \                --user-data file://"${init_file}" --query 'Instances[0].[InstanceId]' | grep -o -E "${INSTANCE_ID_REGEX}")  else    instance_id=$(aws ec2 run-instances --image-id "${image_id}" ${block_device_mappings} --cli-input-json file://json/"${instance_name}".json \                --query 'Instances[0].[InstanceId]' | grep -o -E "${INSTANCE_ID_REGEX}")  fi  create_tags_with_name "${instance_id}" "${instance_name}" "${tags}"}# 为EC2 Instance的指定卷创建快照并删除以前同名快照create_snapshot() {  instance_name=$1  device=$2  snapshot_name=$3  tags=$4  instance_id=$(query_instance_id_by_name "${instance_name}")  delete_snapshot "${snapshot_name}"  volume_id=$(query_volume_id_by_instance_id_and_device ${instance_id} ${device})  if [[ "${volume_id}" ]]; then    echo "create snapshot for volume: ${device} of instance ${instance_name}"    snapshot_id=$(aws ec2 create-snapshot --volume-id ${volume_id} | grep -o -E "${SNAPSHOT_ID_REGEX}")    create_tags_with_name "${snapshot_id}" "${snapshot_name}" "${tags}"  fi}# 根据名称删除快照delete_snapshot() {  snapshot_id=$(query_snapshot_id_by_name "$1")  if [[ "${snapshot_id}" ]]; then    echo "delete snapshot: $1"    aws ec2 delete-snapshot --snapshot-id ${snapshot_id}  fi}# 从快照创建卷并删除旧的重名卷,然后将卷连接到Instance的指定deviceattach_volume() {  snapshot_name=$1  instance_name=$2  device=$3  tags=$4  availability_zone="cn-north-1a"  volume_name="$1-1a"  snapshot_id=$(query_snapshot_id_by_name ${snapshot_name})  instance_id=$(query_instance_id_by_name ${instance_name})  if [[ -z "${snapshot_id}" ]]; then    echo "Please provide valid snapshot name"    exit 1  fi  if [[ -z "${instance_id}" ]]; then    echo "Please provide valid instance name"    exit 1  fi  old_volume_ids=$(query_volume_ids_by_name "${volume_name}")  for id in ${old_volume_ids}  do    echo "delete old volume: $id"    aws ec2 delete-volume --volume-id ${id}  done  echo "create volume ${volume_name} from snapshot ${snapshot_name}(${snapshot_id})"  volume_id=$(aws ec2 create-volume --snapshot-id ${snapshot_id} --availability-zone ${availability_zone} --volume-type gp2 --query 'VolumeId' \            | grep -o -E "${VOLUME_ID_REGEX}")  count=0  while [[ "${count}" -le 0 ]]  do    echo "Creating volume ${volume_name} ..."    count=$(aws ec2 describe-volumes --volume-ids ${volume_id} --query Volumes[0].State | grep -c available)    sleep 3  done  echo "attach volume: ${volume_name} to instance ${instance_name}"  aws ec2 attach-volume --volume-id ${volume_id} --instance-id ${instance_id} --device ${device}  create_tags_with_name "${volume_id}" "${volume_name}" "${tags}"}# 关联弹性IP到Instanceassociate_address() {  instance_id=$(query_instance_id_by_name "$1")  aws ec2 associate-address --instance-id ${instance_id} --public-ip $2}# 更新NAT Instance路由replace_route() {  echo "update route table: $1"  route_table_id=$(query_route_table_id_by_name "$1")  nat_instance_id=$(query_instance_id_by_name "$2")  cidr=$3  aws ec2 replace-route --route-table-id ${route_table_id} --destination-cidr-block ${cidr} --instance-id ${nat_instance_id}}echo_usage() {  echo "Usage: $0 [command] [args ...]"  echo "Commands:"  echo "  create-image [instance_name] [image_name] [tags] Create an AMI from an EC2 instance"  echo "  delete-image [image_name] Delete image by name"  echo "  start-instance [instance_name] Start an EC2 instance"  echo "  start-instances [category_name] Start EC2 instances by category"  echo "  stop-instance [instance_name] Stop an EC2 instance"  echo "  stop-instances [category_name] Stop EC2 instances by category"  echo "  reboot-instance [instance_name] Reboot an EC2 instance"  echo "  reboot-instances [category_name] Reboot EC2 instances by category"  echo "  terminate-instance [instance_name] Terminate an EC2 instance"  echo "  terminate-instances [category_name] Terminate EC2 instances by category"  echo "  run-instance [instance_name] [image_name] [options] Launch an instance using an AMI"  echo "    Options:"  echo "      --device-snapshot-name One block device snapshot name"  echo "      --init-file an user data file"  echo "      --tags One  or more tags"  echo "  create-snapshot [instance_name] [device] [snapshot_name] [tags] Creates a snapshot of the specified volume for an instance"  echo "  delete-snapshot [snapshot_name] Deletes the specified snapshot"  echo "  attach-volume [snapshot_name] [instance_name] [device] [tags] Create a volume from a snapshot, and then attach the volume to an instance"  echo "  associate-address [instance_name] [public_ip]  Associates an Elastic IP address with an instance"  echo "  replace-route [route_table_name] [nat_instance_name] [cidr] Replaces an existing route within a route table in a VPC"}if test @$1 = @--help -o @$1 = @-h; then  echo_usage  exit 0fiif [[ $# -lt 2 ]]; then  echo_usage  exit 1ficase "$1" in  create-image)    create_image "$2" "$3" "$4"    ;;  delete-image)    delete_image "$2"    ;;  start-instance)    start_instance "$2"    ;;  start-instances)    start_instances "$2"    ;;  stop-instance)    stop_instance "$2"    ;;  stop-instances)    stop_instances "$2"    ;;  reboot-instance)    reboot_instance "$2"    ;;  reboot-instances)    reboot_instances "$2"    ;;  terminate-instance)    terminate_instance "$2"    ;;  terminate-instances)    terminate_instances "$2"    ;;  run-instance)    args=`getopt -l init-file:,device-snapshot-name:,tags: -- "$@"`    if [[ $? != 0 ]] ; then     exit 1    fi    instance_name=$2    image_name=$3    device_snapshot_name=""    init_file=""    tags=""    eval set -- "${args}"    while true    do    case "$1" in      --device-snapshot-name)        device_snapshot_name="$2"        shift 2        ;;      --init-file)        init_file="$2"        shift 2        ;;      --tags)        tags="$2"        shift 2        ;;      --)        shift        break        ;;    esac    done    run_instance "${instance_name}" "${image_name}" "${device_snapshot_name}" "${init_file}" "${tags}"    ;;  create-snapshot)    create_snapshot "$2" "$3" "$4" "$5"    ;;  delete-snapshot)    delete_snapshot "$2"    ;;  attach-volume)    attach_volume "$2" "$3" "$4" "$5"    ;;  associate-address)    associate_address "$2" "$3"    ;;  replace-route)    replace_route "$2" "$3" "$4"    ;;  *)    exit 1    ;;esac

从image运行instance时需要使用json配置文件,位置在json目录下,名称要与instance name相同,内容如下;
示例ec2.json

{    "DryRun": false,     "KeyName": "AWS Prod Key Pair",    "SecurityGroupIds": [        "sg-1361c577"    ],    "InstanceType": "m4.large",     "Placement": {        "AvailabilityZone": "cn-north-1a",         "Tenancy": "default"    },     "Monitoring": {        "Enabled": false    },     "DisableApiTermination": true,     "InstanceInitiatedShutdownBehavior": "stop",     "NetworkInterfaces": [        {            "DeviceIndex": 0,            "SubnetId": "subnet-d45208b1",            "PrivateIpAddress": "10.184.12.246",            "DeleteOnTermination": true,            "AssociatePublicIpAddress": false        }    ],    "EbsOptimized": false}

示例

$ ./ec2.sh run-instance test-app1 test-app1 --tags "Key=CCX,Value=DSC003 Key=Project,Value=Test"

RDS

rds.sh

#!/bin/bash# 根据db-instance-identifier删除数据库,删除前先创建快照,并将db-snapshot-identifier保存在文件中delete() {  echo "deleting database $1 ..."  snapshot_id="$1-$(date +%Y%m%d)"  aws rds delete-db-instance --db-instance-identifier "$1" --no-skip-final-snapshot --final-db-snapshot-identifier "${snapshot_id}"  echo "${snapshot_id}" > "$(dirname $0)/$1.snapshot.id"}# 从最近的快照恢复数据库,数据库配置从json文件读取,恢复成功后指定security group,并输出恢复日志到文件中restore() {  log_file="$(dirname $0)/restore.log"  id_file="$(dirname $0)/$1.snapshot.id"  snapshot_id=$(cat ${id_file})  echo "Restore database $1 from snapshot ${snapshot_id}" | tee ${log_file}  aws rds restore-db-instance-from-db-snapshot --db-snapshot-identifier "${snapshot_id}" --cli-input-json file://json/"$1".json | tee ${log_file}  count=0  while [[ "${count}" -le 0 ]]  do    echo "Creating database $1 ..."    count=$(aws rds describe-db-instances --db-instance-identifier "$1" --query 'DBInstances[0].[DBInstanceStatus]' | grep -c available)    sleep 5  done  echo "Modify database $1" | tee ${log_file}  aws rds modify-db-instance --db-instance-identifier "$1" --vpc-security-group-ids $2 | tee ${log_file}}echo_usage() {  echo "Usage: $0 [delete|restore] [args ...]"  echo "Commands:"  echo "  delete [db-instance-identifier] Delete a DB instance"  echo "  restore [db-instance-identifier] [vpc-security-group-ids] Create a new DB instance from a DB snapshot"}if test @$1 = @--help -o @$1 = @-h; then  echo_usage  exit 0fiif [[ $# -lt 2 ]]; then  echo_usage  exit 1ficase "$1" in  delete)    delete "$2"    ;;  restore)    restore "$2" "$3"    ;;  *)    exit 1    ;;esac

示例dn.json

{    "DBInstanceIdentifier": "test",    "DBInstanceClass": "db.r3.large",     "Port": 1521,     "AvailabilityZone": "cn-north-1a",     "DBSubnetGroupName": "test-db",    "MultiAZ": false,     "PubliclyAccessible": false,     "AutoMinorVersionUpgrade": true,     "LicenseModel": "license-included",     "DBName": "test",    "Engine": "oracle-se1",     "OptionGroupName": "default:oracle-se1-11-2",     "StorageType": "standard",     "CopyTagsToSnapshot": true}

CloudWatch

cloudwatch.sh

#!/bin/bash. $(dirname $0)/common.sh# 当EC2 Instance CPU利用率超过90%时发送邮件告警cpu() {  instance_name=$1  sns_topic_arn=$2  instance_id=$(query_instance_id_by_name "${instance_name}")  aws cloudwatch put-metric-alarm --alarm-name "cpu-${instance_name}" --alarm-description "Alarm when CPU exceeds 90 percent" --metric-name CPUUtilization \  --namespace AWS/EC2 --statistic Average --period 300 --threshold 90 --comparison-operator GreaterThanThreshold \  --dimensions "Name=InstanceId,Value=${instance_id}" --evaluation-periods 2 --unit Percent --alarm-actions $2}echo_usage() {  echo "Usage: $0 [cpu] [instance_name] [sns_topic_arn]"}if test @$1 = @--help -o @$1 = @-h; then  echo_usage  exit 0fiif [[ $# -lt 2 ]]; then  echo_usage  exit 1ficase "$1" in  "cpu")    cpu "$2" "$3"    ;;  *)    exit 1    ;;esac
0