Skip to content

shaurya-security/aws-infra-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

aws-infra-cli

A Bash CLI toolkit for managing AWS infrastructure — built from the AWS CLI up, with no Terraform, no CloudFormation, no console.

Every AWS resource has its own independent function. create_vpc, create_subnet, authorize_ingress, launch_bastion, ssh_webserver — each works standalone, tracks its own state locally, and composes cleanly with everything else.

create_environment is one of those compositions. It is not the point.


Background

This grew out of a failed attempt to rebuild Phase 4 AWS infrastructure from memory. The guided lab had covered everything. The understanding hadn't stuck.

Rather than work around the gap, I stopped the next project and rebuilt from scratch — one resource at a time, no guidance, just the AWS CLI reference. The functions accumulated because the problems did. See docs/STORY.md for the full account.


What it actually is

Eight modules covering every layer of AWS networking and compute. Each module is independently usable.

Need one subnet? Run create_subnet. Need to revoke one SG rule? Run revoke_ingress. Need to SSH into the WebServer? Run ssh_webserver — it detects your current IP, updates the security group rule, and connects through the Bastion in one step.

Every function is independently usable and composable.

For example, a custom environment is just another shell function:

create_lab() {
    create_vpc
    create_subnet
    create_subnet
    create_igw
    attach_igw
    create_route_table
    create_route
    launch_bastion
    launch_webserver
}

The toolkit does not distinguish between "manual" and "automated" workflows. create_environment is simply a predefined composition of the same primitives.

Adjust the name pool in common.sh. Run it. Done. The orchestration is just another wrapper.

create_environment works the same way — 14 functions called in the correct sequence. Subnets before route tables. Route tables before associations. IGW before routes. DNS after the VPC is stable. The dependency order is the knowledge. The automation is a consequence.


Infrastructure the full environment builds

VPC (10.0.0.0/16)
├── Public Subnet  (10.0.1.0/24)  →  Bastion EC2  (public IP, SSH from your IP only)
├── Private Subnet (10.0.2.0/24)  →  WebServer EC2 (private IP, SSH via Bastion)
├── Internet Gateway
├── Route Tables   (public: 0.0.0.0/0 → IGW  |  private: 0.0.0.0/0 → Bastion ENI)
└── Security Groups (chained: Bastion → WebServer → Database)

The Bastion can be configured as a NAT instance, giving the private subnet outbound internet access without a managed NAT Gateway.


Functions by module

Module What it covers
vpc.sh create_vpc, list_vpcs, select_vpc, delete_vpc, delete_all_vpcs
subnet.sh create_subnet, list_subnets, select_subnet, delete_subnet, delete_all_subnets
dns_igw.sh create_igw, attach_igw, detach_igw, enable_dns, disable_dns, detach_all_igws, delete_all_igws
route_tables.sh create_route_table, create_route, associate_route_table, disassociate_route_table, delete_all_routes, delete_all_route_tables, delete_all_associations
sg.sh create_security_group, authorize_ingress, revoke_ingress, list_rules, create_bastion_sg, create_webserver_sg, create_database_sg, delete_all_rules, delete_all_sgs
instance.sh launch_bastion, launch_webserver, launch_instance, enable_nat_instance, ssh_bastion, ssh_webserver, refresh_bastion_access_in_sg, start_all_instances, stop_all_instances, delete_all_instances
infra.sh create_environment, list_environment, auto_delete_environment

Demo

A complete cycle was run on 2026-06-06. Full terminal output and screenshots are in demo/.

demo/screenshots/README.md is one scrollable file — function source first, then terminal output, for each operation. The three orchestration functions (create_environment, list_environment, auto_delete_environment) are shown as code screenshots so the structure of the tool is visible alongside what it produces.

The NAT proof is the most concrete part: ping google.com from a private EC2 with no public IP — 100% loss before the Bastion bootstrap, 0% loss after. The route table, the source/destination check, the iptables MASQUERADE rule — all of it visible in the logs.


Quick start

# Prerequisites: AWS CLI v2 configured, Bash 5+, ssh-agent running

git clone https://github.com/your-username/aws-infra-cli.git
cd aws-infra-cli

source scripts/infra.sh

From there, every function is available in your shell. Call them individually or run create_environment for the full stack.

See docs/SETUP.md for prerequisites and configuration.


Repository layout

aws-infra-cli/
├── scripts/
│   ├── com_arg.sh        # Central config: name pools, DB paths, color functions
│   ├── vpc.sh            # VPC lifecycle
│   ├── subnet.sh         # Subnet lifecycle, auto CIDR assignment
│   ├── dns_igw.sh        # Internet Gateway + DNS settings
│   ├── route_tables.sh   # Route tables, routes, subnet associations
│   ├── sg.sh             # Security groups and ingress rules
│   ├── instance.sh       # EC2, key pairs, NAT, SSH shortcuts
│   └── infra.sh          # Orchestration: create / list / delete
├── docs/
│   ├── SETUP.md          # Prerequisites and configuration
│   ├── ARCHITECTURE.md   # Component design and NAT flow
│   ├── DESIGN.md         # Key design decisions
│   ├── BUGS.md           # Mistakes made and how each was fixed
│   └── STORY.md          # How this got built
├── demo/
│   └── screenshots/      # Terminal output captures, organized by operation
├── database/             # Runtime state (.db files, excluded from git)
│   └── counters/
├── .gitignore
└── README.md

How state is tracked

Each resource ID is stored locally in a pipe-delimited .db file on creation and removed on deletion. No querying AWS by tag — tag-based filters return terminated instances, which caused real bugs during development (documented in docs/BUGS.md).

database/vpcs.db            →  vpc-id|name
database/subnets.db         →  subnet-id|name|type|vpc-id|cidr-octet
database/security_groups.db →  sg-id|name|description|vpc-id
database/ec2.db             →  instance-id|name|subnet-id|sg-id|state

Twelve .db files in total. State survives session resets. See docs/ARCHITECTURE.md for the full schema.


Tech stack

Layer Details
Language Bash 5+
Cloud AWS CLI v2
State Flat pipe-delimited .db files
SSH Agent forwarding, jump through Bastion
NAT Bastion as NAT instance (source/dest check disabled, iptables MASQUERADE)

Project status

  • Full networking stack: VPC, subnets, IGW, route tables, security groups
  • Compute: key pair management, AMI caching, EC2 launch and lifecycle
  • NAT: Bastion as NAT instance with idempotent setup
  • SSH: automatic SG IP refresh before every connection
  • Cleanup: full teardown in correct dependency order
  • CloudTrail integration (planned)
  • S3 bucket management (planned)
  • IAM least-privilege templates (planned)

License

MIT

About

AWS infrastructure automation toolkit built with Bash and AWS CLI. 110+ functions across 8 modules managing VPCs, subnets, EC2, NAT, routing, and security groups without Terraform or CloudFormation.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages