AWS CLI:开发者的秘密武器(以及如何确保其安全)
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,你可以:
- 在毫秒级启动数十个资源,而不是分钟
- 同时跨地区查询多个服务
- 使用
jq、grep、awk、sed等强大工具即时过滤和处理输出 - 将命令串联起来实现复杂工作流
- 为常用操作培养肌肉记忆
**具体示例:**查找四个地区中所有正在运行但已闲置超过 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 将基础设施视作代码,你可以获得开发者在编写应用代码时享有的同等好处——可重复性、版本化以及协作。