AWS CLI Automation with Bash
Automate AWS resource provisioning, tagging, and cleanup using Bash scripts wrapped around the AWS CLI.
Note: This guide follows English-language naming conventions and terminology standards common in international development teams. Examples use English identifiers and comments to maximize compatibility across codebases and tooling.
Overview
The AWS CLI is powerful but verbose. Wrapping it in Bash scripts lets you provision, tag, and clean up resources consistently across environments. Whether you are spinning up a test stack, enforcing tagging policies, or removing unused resources, a script reduces copy-paste errors and makes operations repeatable.
When to Use
Use this resource when:
- You need to create or destroy AWS resources repeatedly.
- You want to enforce consistent tagging across resources.
- You are automating cleanup of development or sandbox environments.
- You prefer shell scripts over Terraform or CloudFormation for simple tasks.
Solution
AWS CLI automation script
#!/usr/bin/env bash
set -euo pipefail
REGION="${AWS_REGION:-us-east-1}"
PROJECT="${1:-demo}"
ENV="${2:-dev}"
TAGS="Key=Project,Value=$PROJECT Key=Environment,Value=$ENV Key=ManagedBy,Value=bash-script"
# Create a VPC with tags
VPC_ID=$(aws ec2 create-vpc --cidr-block 10.0.0.0/16 --region "$REGION" --query 'Vpc.VpcId' --output text)
aws ec2 create-tags --resources "$VPC_ID" --tags $TAGS --region "$REGION"
# Create a subnet
SUBNET_ID=$(aws ec2 create-subnet --vpc-id "$VPC_ID" --cidr-block 10.0.1.0/24 --region "$REGION" --query 'Subnet.SubnetId' --output text)
aws ec2 create-tags --resources "$SUBNET_ID" --tags $TAGS --region "$REGION"
# Cleanup function
cleanup() {
echo "Cleaning up resources..."
aws ec2 delete-subnet --subnet-id "$SUBNET_ID" --region "$REGION" || true
aws ec2 delete-vpc --vpc-id "$VPC_ID" --region "$REGION" || true
}
trap cleanup EXIT
echo "Created VPC $VPC_ID and subnet $SUBNET_ID"
Explanation
The script reads the AWS region from an environment variable and accepts project and environment names as arguments. It creates a VPC, tags it, creates a subnet, tags it, and registers a cleanup trap that deletes both resources when the script exits. Using || true in the cleanup function prevents a failure during teardown from failing the whole script. The --query and --output text flags extract just the resource IDs needed for subsequent commands.
Variants
| Task | AWS CLI command | Notes |
|---|---|---|
| List untagged | aws ec2 describe-instances | Filter by tag absence |
| Tag resources | aws ec2 create-tags | Bulk tag by resource IDs |
| Delete old | aws ec2 describe-snapshots | Filter by date, then delete |
| Assume role | aws sts assume-role | Use temporary credentials |
Best Practices
- Use
--queryand--output textto parse IDs. Avoid fragile text parsing of JSON or tables. - Tag everything immediately. Tags are easier to add at creation than to retroactively apply.
- Add a cleanup trap for temporary resources. This prevents leftover test infrastructure from increasing your bill.
- Assume least-privilege roles. Use
aws sts assume-roleinstead of long-lived access keys. - Validate with
--dry-runfirst. AWS CLI supports dry-run for many mutating calls, especially EC2.
Common Mistakes
- Hardcoding credentials in scripts. Use IAM roles, environment variables, or AWS SSO instead.
- Forgetting to handle dependencies. You cannot delete a VPC that still has subnets or dependencies.
- Not trapping cleanup. A failed script leaves resources running and accruing charges.
- Using the default region silently. Always set
AWS_REGIONor pass--regionexplicitly. - Ignoring API rate limits. Large scripts can hit throttling; add retries or slow down with
aws configureretry mode.
Frequently Asked Questions
Q: How do I run this in CI? A: Use OIDC or short-lived credentials from AWS SSO. Never commit access keys to CI variables.
Q: Should I use this instead of Terraform? A: For one-off or exploratory tasks, Bash plus AWS CLI is fine. For production infrastructure, use Terraform or CloudFormation for state management and drift detection.
Q: How do I find and delete untagged resources?
A: Use aws resourcegroupstaggingapi get-resources and then delete the returned ARNs with the appropriate service commands.
Related Resources
Bash Scripting for DevOps Automation and System Tasks
How to write robust Bash scripts for automating deployments, system monitoring, log rotation, and routine maintenance tasks
RecipeBackup Rotation Script
Automate file backups with retention policies using a Bash script that rotates daily, weekly, and monthly snapshots.
RecipeSSH Key Management
Generate, rotate, and distribute SSH keys securely with Bash scripts for team and server access.
RecipeConfigure Firewall Rules with iptables
Set up basic firewall rules using iptables in Bash to filter traffic, block ports, and protect Linux servers.
RecipeLog Rotation and Compression
Rotate and compress application logs with Bash to prevent disk exhaustion and simplify log retention.