AWS CLI:开发者的秘密武器(以及如何确保其安全)

发布: (2025年12月7日 GMT+8 14:34)
7 min read
原文: Dev.to

Source: Dev.to

为什么终端是 AWS 管理的最佳伙伴

如果你一直只通过网页控制台管理 AWS 资源,并没有错——但你可能比实际需要的更费劲。让我来说明为什么 AWS CLI 已经成为那些重视速度、自动化和控制的开发者的首选。

网页控制台还行……直到它不行

别误会——AWS 管理控制台设计精美。它直观、可视,特别适合你在学习服务时进行探索。亚马逊投入了数百万打造一个让每个人都能使用云计算的界面,这点值得赞赏。

但在真实的开发场景中会发生这样的情况:

控制台工作流

  • 打开浏览器 → 等待页面加载 → 进入 AWS → 多因素认证的舞步 → 从 200 多个选项中找到正确的服务 → 点击多个页面 → 一次一个字段地配置设置 → 等待确认 → 发现你需要在另外三个地区做完全相同的配置 → 手动复制设置 → 为下一个资源重复 → 发现还要再做 47 次 → 质疑自己的职业选择 → 考虑去当农民

CLI 工作流

aws ec2 run-instances --image-id ami-12345678 --count 50 --instance-type t2.micro --key-name MyKeyPair --region us-east-1

一行命令。五十个实例。配合简单循环即可在多个地区完成。总耗时五秒。

区别不仅在于速度——而是对基础设施管理思维方式的根本转变。控制台让你习惯点击操作,CLI 让你习惯系统化思考。

为什么聪明的开发者选择 CLI

1. 真正重要的速度

当你在部署基础设施、凌晨 2 点排查问题,或在多个 AWS 账户和地区之间管理资源时,每一秒都在累加。使用 CLI,你可以:

  • 在毫秒级启动数十个资源,而不是分钟
  • 同时跨地区查询多个服务
  • 使用 jqgrepawksed 等强大工具即时过滤和处理输出
  • 将命令串联起来实现复杂工作流
  • 为常用操作培养肌肉记忆

**具体示例:**查找四个地区中所有正在运行但已闲置超过 30 天的 EC2 实例。

for region in us-east-1 us-west-2 eu-west-1 ap-southeast-1; do
  aws ec2 describe-instances --region $region \
    --filters "Name=instance-state-name,Values=running" \
    --query 'Reservations[*].Instances[*].[InstanceId,LaunchTime]' \
    --output text | while read id launch_time; do
      # 检查实例是否超过 30 天
      if [[ $(date -d "$launch_time" +%s) -lt $(date -d '30 days ago' +%s) ]]; then
        echo "$region: $id (launched: $launch_time)"
      fi
    done
done

写两分钟,执行瞬间完成,结果完整。

2. 自动化与脚本化:CLI 的不可或缺之处

CLI 不仅省时,还能开启全新的工作流。

自动备份脚本

#!/bin/bash
# 所有 RDS 实例的每日备份脚本
BACKUP_DATE=$(date +%Y%m%d-%H%M%S)

# 获取所有 RDS 实例
for db in $(aws rds describe-db-instances \
  --query 'DBInstances[*].DBInstanceIdentifier' \
  --output text); do

  echo "Creating snapshot for $db..."
  aws rds create-db-snapshot \
    --db-instance-identifier $db \
    --db-snapshot-identifier "${db}-backup-${BACKUP_DATE}"

  # 为快照打标签
  aws rds add-tags-to-resource \
    --resource-name "arn:aws:rds:us-east-1:123456789012:snapshot:${db}-backup-${BACKUP_DATE}" \
    --tags Key=AutomatedBackup,Value=true Key=Date,Value=$BACKUP_DATE

  # 删除 30 天前的快照
  aws rds describe-db-snapshots \
    --db-instance-identifier $db \
    --query "DBSnapshots[?SnapshotCreateTime<='$(date -d '30 days ago' --iso-8601)'].DBSnapshotIdentifier" \
    --output text | while read old_snapshot; do
      echo "Deleting old snapshot: $old_snapshot"
      aws rds delete-db-snapshot --db-snapshot-identifier $old_snapshot
    done
done

echo "Backup process completed at $(date)"

使用 cron 调度,实现企业级备份自动化。

成本优化脚本

#!/bin/bash
# 在下午 6 点后停止所有标记为 "Environment:Development" 的 EC2 实例

CURRENT_HOUR=$(date +%H)

if [ $CURRENT_HOUR -ge 18 ]; then
  aws ec2 describe-instances \
    --filters "Name=tag:Environment,Values=Development" \
              "Name=instance-state-name,Values=running" \
    --query 'Reservations[*].Instances[*].InstanceId' \
    --output text | while read instance; do
      echo "Stopping development instance: $instance"
      aws ec2 stop-instances --instance-ids $instance

      # 发送通知
      aws sns publish \
        --topic-arn "arn:aws:sns:us-east-1:123456789012:cost-savings" \
        --message "Stopped development instance $instance at $(date)"
    done
fi

这样的一段脚本即可在非工作时间自动关闭开发环境,每月为公司节省数千美元。

3. 基础设施的版本控制

你的 CLI 命令写在脚本里,脚本放在 Git 中。这为你提供了:

  • 完整审计历史——每一次基础设施变更都是带有时间戳和作者的 Git 提交。
  • 代码审查流程——变更必须通过 Pull Request 才能进入生产环境。
  • 回滚能力——git revert 成为基础设施的撤销按钮。
  • 团队协作——每个人都能看到、审查并改进基础设施代码。
  • 文档化——脚本本身就是基础设施工作原理的文档。

示例:VPC 创建脚本

#!/bin/bash
# vpc-setup.sh – 创建完整的 VPC 环境

# 创建 VPC
VPC_ID=$(aws ec2 create-vpc \
  --cidr-block 10.0.0.0/16 \
  --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=Production-VPC}]' \
  --query 'Vpc.VpcId' \
  --output text)

echo "Created VPC: $VPC_ID"

# 创建 Internet Gateway
IGW_ID=$(aws ec2 create-internet-gateway \
  --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=Production-IGW}]' \
  --query 'InternetGateway.InternetGatewayId' \
  --output text)

aws ec2 attach-internet-gateway --vpc-id $VPC_ID --internet-gateway-id $IGW_ID
echo "Created and attached Internet Gateway: $IGW_ID"

# 创建公共子网
PUBLIC_SUBNET_ID=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.1.0/24 \
  --availability-zone us-east-1a \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Public-Subnet-1a}]' \
  --query 'Subnet.SubnetId' \
  --output text)

echo "Created public subnet: $PUBLIC_SUBNET_ID"

# 创建私有子网
PRIVATE_SUBNET_ID=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.2.0/24 \
  --availability-zone us-east-1a \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Private-Subnet-1a}]' \
  --query 'Subnet.SubnetId' \
  --output text)

echo "Created private subnet: $PRIVATE_SUBNET_ID"

# 为公共子网创建路由表
ROUTE_TABLE_ID=$(aws ec2 create-route-table \
  --vpc-id $VPC_ID \
  --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=Public-RT}]' \
  --query 'RouteTable.RouteTableId' \
  --output text)

echo "Created route table: $ROUTE_TABLE_ID"

通过使用 AWS CLI 将基础设施视作代码,你可以获得开发者在编写应用代码时享有的同等好处——可重复性、版本化以及协作。

Back to Blog

相关文章

阅读更多 »

Jenkins 在 AWS + Docker

Jenkins 在 AWS + Docker 的封面图片 https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-upload...