AWS EC2 CLI: Launch, Inspect, Stop, and Automate Instances
The AWS Command Line Interface turns EC2 administration into repeatable commands that can be reviewed, scripted, versioned, and combined with other automation. That is more powerful than clicking through the console, but it also removes some of the visual guardrails that make mistakes obvious. Efficient EC2 CLI work therefore depends on three habits: scope commands precisely, inspect state before changing it, and make repeatable configuration explicit.
AWS now recommends AWS CLI version 2 for current work; CLI v1 entered maintenance mode in August 2026. The examples below use the current v2 command model. They are intentionally small and should be adapted to your account, Region, IAM permissions, launch templates, networking, and security requirements.
Every EC2 command runs in an identity and a Region. Confirm both before making changes. Profiles help separate accounts or roles, while explicit --region flags remove ambiguity in automation. Use least-privilege IAM permissions instead of broad administrative credentials, and avoid storing long-lived access keys in scripts or source repositories.
aws sts get-caller-identity
aws configure list
aws ec2 describe-instances --region us-east-1 --max-results 5
Those checks establish who you are and where you are operating. This matters because an apparently empty result can mean “wrong Region,” not “no instances.” The broader cloud engineer skill map reinforces the same principle: cloud operations are inseparable from identity, networking, automation, reliability, security, and cost.
describe-instances can return every instance in a Region, which becomes noisy and slow in larger environments. Filter by tag, state, VPC, subnet, instance type, or explicit instance ID. Combine filters with JMESPath queries to return only the fields an operator or script needs.
aws ec2 describe-instances --filters "Name=tag:Environment,Values=prod" "Name=instance-state-name,Values=running" --query "Reservations[].Instances[].{Id:InstanceId,Type:InstanceType,AZ:Placement.AvailabilityZone,Name:Tags[?Key=='Name']|[0].Value}" --output table
Filtering is a safety feature as much as a convenience. A command designed around a known tag set is easier to review than one that fetches everything and expects a human to spot the right instance in a long list.
run-instances supports many individual parameters, but production workflows are easier to control with launch templates. A launch template can centralize the AMI, instance type defaults, security groups, storage configuration, IAM instance profile, metadata options, and other settings. The CLI command then focuses on what varies for the current launch.
aws ec2 run-instances --launch-template LaunchTemplateName=web-prod,Version='$Latest' --subnet-id subnet-0123456789abcdef0 --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=web-01},{Key=Environment,Value=prod}]'
For one-off learning, specifying an AMI and instance type directly is fine. For repeatable operations, templates reduce drift and make change review easier. They also fit the mindset validated by the AWS CloudOps Engineer – Associate path: operational work should be observable, repeatable, and governed rather than dependent on individual console memory.
Stopping an EBS-backed instance releases its compute resources while EBS volumes persist and continue to incur storage charges. Starting it allocates compute again. A reboot restarts the operating system without the same stop/start lifecycle. Termination is destructive according to the instance’s delete-on-termination settings and cannot be treated as a temporary power state.
aws ec2 stop-instances --instance-ids i-0123456789abcdef0
aws ec2 start-instances --instance-ids i-0123456789abcdef0
Before bulk actions, describe the targeted instances and check tags, state, Auto Scaling membership, and application role. An instance in an Auto Scaling group may be replaced rather than simply left stopped. State-changing commands should be built around the workload’s architecture, not around the machine as an isolated object.
EC2 state changes are asynchronous. A successful API response often means the transition started, not that the target state is already usable. AWS CLI waiters let automation pause until a defined state is reached.
aws ec2 start-instances --instance-ids i-0123456789abcdef0
aws ec2 wait instance-running --instance-ids i-0123456789abcdef0
aws ec2 describe-instance-status --instance-ids i-0123456789abcdef0
This is safer than fixed sleep intervals. A thirty-second sleep can be unnecessarily slow when an instance is ready in ten seconds and dangerously short when a transition takes longer. Wait for the state you actually require, then perform the next operation.
Tags should identify purpose, environment, owner, application, cost center, and automation policy where appropriate. Good tags allow scripts to target groups without hard-coding instance IDs and help cost, security, and operations teams understand what a resource belongs to.
Do not make a destructive command depend on a broad tag alone without additional validation. For example, a shutdown script can query Environment=dev, print the candidate list, exclude protected workloads, and then act. The difference between reliable automation and dangerous automation is often a verification step.
The CLI can emit JSON, YAML, text, or tables. JSON is useful for programmatic processing, while tables are convenient for human review. JMESPath queries let you select fields, count instances, sort output, and create concise inventories without external tools.
aws ec2 describe-instances --filters "Name=instance-state-name,Values=running" --query "length(Reservations[].Instances[])"
The Azure Administrator and AWS CloudOps Engineer roles both require disciplined inventory, monitoring, permissions, lifecycle control, and recovery. The CLI is only one interface into that operating model.
Use --dry-run where the API supports it to test whether the caller has permission. Validate input IDs. Require an expected account ID or profile. Check tags before state changes. Log commands and results. Treat non-zero exit codes as failures instead of continuing blindly. For production scripts, make retries and idempotency explicit where operations can be repeated.
The AWS CloudOps Engineer Associate SOA-C03 expands EC2 command-line practice into broader monitoring, resilience, networking, security, and operational automation skills. The exam role covers deployment, management, and operations rather than memorizing isolated commands.
Memorizing run-instances, describe-instances, start-instances, and stop-instances is a starting point. Real fluency is knowing which instance should be changed, what other services depend on it, whether data persists, which identity is acting, how you will confirm success, and how the command fits a repeatable operational procedure.
Start with small commands you can explain. Add filters and queries. Move stable launch configuration into templates. Use waiters for state transitions and tags for targeting. Once those habits are consistent, the EC2 CLI becomes not just a faster console replacement but a dependable foundation for automation.
For fleet operations, combine the CLI with systems that manage desired state rather than inventing a homegrown loop for everything. Systems Manager, Auto Scaling, launch templates, CloudWatch, EventBridge, and infrastructure-as-code tools can each own part of the lifecycle. The CLI is excellent for inspection, controlled administrative actions, and automation glue, but a production environment should not depend on one operator repeatedly issuing imperative commands to keep machines consistent.
Cost control belongs in EC2 administration as well. Stopped EBS-backed instances no longer incur instance compute charges, but attached EBS storage can continue to cost money, and other resources such as Elastic IP addresses or snapshots may have their own billing behavior. Inventory scripts should therefore report related resources and ownership, not merely instance state. A “stopped” label is not the same as “free.”
Troubleshooting also becomes faster when commands are built around hypotheses. If an instance is unreachable, inspect state, system status, instance status, network interfaces, security groups, routes, and relevant logs rather than restarting blindly. If a launch fails, review the returned error, IAM permissions, quota, subnet capacity, AMI compatibility, and launch-template settings. The CLI provides precise evidence; efficient operations come from asking it the right question.
For recurring workflows, store command logic in version-controlled scripts and review changes just as you would application code. Parameterize account-specific values, avoid embedding secrets, and add a confirmation or approval boundary for destructive operations. Test the script in a nonproduction environment with representative tags and permissions. The safest CLI automation is boring: predictable inputs, explicit scope, observable output, and a clear failure path when assumptions are not met.
Pagination and throttling deserve attention in larger estates. Commands that work instantly in a lab can behave differently when hundreds or thousands of resources are returned. Use filters, pagination controls, and bounded queries so inventory scripts do not create unnecessary API load. For automation that retries after throttling, use backoff rather than tight repeated requests. Scalability applies to operational tooling as well as to the workloads being managed.
Document the commands that are approved for common incidents and maintenance tasks. A short runbook should state prerequisites, expected output, rollback or recovery steps, and escalation conditions. This reduces improvisation during outages and makes peer review possible before a command becomes part of routine operations.
Runbooks should be tested periodically so they remain accurate when services, permissions, or team responsibilities change. Record AWS CLI version assumptions and required IAM permissions alongside each runbook command. An outdated operational command can be more dangerous than having no automation at all. Keep command examples scoped to named resources or tags whenever possible, because broad account-wide actions deserve stronger review and rollback controls.
