Stop multiple RDS instances using AWS CLI command - amazon-web-services

I have been trying to stop multiple instances of RDS using a single command line but it does not seem to work.
Currently I can only make it work with one instance at a time with a command like this:
aws rds stop-db-instance --db-instance-identifier test-instance1 --region ap-southeast-1 --profile dev
However I would like to stop multiple RDS and this does not seem to work:
aws rds stop-db-instance --db-instance-identifier test-instance1 test-instance2 testinstance3 --region ap-southeast-1 --profile dev
Any idea or suggestion on how I can make this work?
If it is not possible I will probably create a CRON job instead using Lambda.

Sadly you can't do this. But you can write a simple bash for loop:
ids=(test-instance1 test-instance2 test-instance3)
for id in ${ids[#]};
do
echo "Stopping: ${id}"
aws rds stop-db-instance --db-instance-identifier ${id} --region ap-southeast-1 --profile dev
done

If writing a shell script that calls aws rds stop-db-instance multiple times, once per RDS instance, is problematic for you somehow, then consider doing this via a scheduled Lambda (think of it like crontab).
See Schedule Amazon RDS stop and start using AWS Lambda, which:
presents a solution using AWS Lambda and Amazon EventBridge that allows you to schedule a Lambda function to stop and start the idle databases with specific tags to save on compute costs.

Related

RDS instances script automation

I am trying to create a bash script that will find my rds instance with a particular tag and stop the instance.
For example, if my rds instance is running with the tag Name=application_name and value=abc, it should provide me the list of the instance and then stop those.
You should be able to use something like:
ID=$(aws resourcegroupstaggingapi get-resources --resource-type-filters rds:instance --tag-filters Key=application_name,Values=abc --output text)
aws rds stop-db-instance --db-instance-identifier $ID
I didn't test it, but that should get you going!
See: get-resources — AWS CLI Command Reference

How to delete autoscaling groups with aws cli?

I am trying to write a bash script that will delete my EC2 instances and the auto scaling group that launched them:
EC2s=$(aws ec2 describe-instances --region=eu-west-3 \
--filters "Name=tag:Name,Values=*-my-dev-eu-west-3" \
--query "Reservations[].Instances[].InstanceId" \
--output text)
for id in $EC2s
do
aws ec2 terminate-instances --region=eu-west-3 --instance-ids $id
done
aws autoscaling delete-auto-scaling-group --region eu-west-3 \
--auto-scaling-group-name my-asg-dev-eu-west-3
But it fails with this error:
An error occurred (ResourceInUse) when calling the DeleteAutoScalingGroup operation:
You cannot delete an AutoScalingGroup while there are instances or pending Spot
instance request(s) still in the group.
There is no issue if I use the AWS console to do the same thing. Why does the aws cli prevent me from deleting the ASG if I have terminated all the instances?
if you really want to do this with CLI, you may first want to use aws autoscaling suspend-processes command to prevent ASG from creating new instances. Then use aws ec2 terminate-instances like you are doing. Then use aws ec2 wait instance-terminated command and pass instance ids. Once all that is done, you should be able use aws autoscaling delete-auto-scaling-group
aws ec2 terminate-instances will return before the instances have finished terminating (which could take several minutes).
I highly recommend using something like CloudFormation or Terraform for this sort of thing instead of the AWS CLI tool.
You can force delete the ASG with active spot instance requests with AWS cli:
aws autoscaling delete-auto-scaling-group --auto-scaling-group-name Your-ASG-Name --force-delete

How to terminate multiple EC2 instances in AWS via CLI?

I'm looking for terminating multiple EC2 instances via AWS CLI. Yes, can able to terminate an EC2 instance by executing the below command.
Syntax:
aws ec2 terminate-instances --instance-ids <intance id> --profile <profile name>
Example:
aws ec2 terminate-instances --instance-ids <i-...> --profile xxx
But I have a big list of instances that I need to terminate so I'm searching for a solution to terminating a batch of EC2 instances by providing the list of instance ids. I tried with multiple instance ids as below but those not working.
aws ec2 terminate-instances --instance-ids ("instance-id1", "intance-id2") --profile xxx
aws ec2 terminate-instances --instance-ids ("instance-id1intance-id2") --profile xxx
aws ec2 terminate-instances --instance-ids (instance-id1,intance-id2) --profile xxx
Kindly let me know if there is any possibility to terminate a batch of instances.
I can able to achieve this by following the below command as recommended by luk2302
aws ec2 terminate-instances --instance-ids instance-id1 instance-id2 --profile xxx
Also as recommended by Alex Bailey, we can try with the shell script (.sh) or batch (.bat) which will make our job easier.
Instead of running all the instance ID's through at once I would create a loop in a shell script to do this.
Assuming you have each instance ID on a separate line in a text file you could do something like:
#!/usr/bin/env bash
while read ins_id; do
aws ec2 terminate-instances --instance-ids $ins_id --profile <profile name> || echo "error terminating ${ins_id}"
done < instance_ids.txt
That's not tested and I'm not great with shell scripting so if you try using it just try with one or two instances first and see what happens.

AWS RDS status while creating the RDS via CLI

I am creating the RDS via AWS CLI using
create-db-instance
RDS is getting created but I want to wait until the RDS comes to "available" state so that I can execute the remaining part of the script. I am not sure how can I achieve that.
Use the waiters as provided by the AWS SDK in its CLI. Specifically, you want to wait until RDS DB instance becomes available. Look at db-instance-available.
aws rds wait \
db-instance-available \
--db-instance-identifier "your-rds-instnace-id"
Never tried this. But the following CLI is what you need:
aws rds wait db-instance-available --db-instance-identifier <value>
Wait until JMESPath query DBInstances[].DBInstanceStatus returns
available for all elements when polling with describe-db-instances. It
will poll every 30 seconds until a successful state has been reached.
This will exit with a return code of 255 after 60 failed checks.
These days, you should use the AWS Command-Line Interface (CLI) to call AWS.
The command would be:
aws rds create-db-instance ...
Then, you could call a waiter:
aws rds wait db-instance-available ...
See:
create-db-instance
db-instance-available

How to find latest or most recent AWS RDS snapshot?

I can call aws rds describe-db-snapshots --db-instance-identifier {my_db_instance} and sort all automated snapshots to find the most recently created one but I was hoping someone has a better idea out there.
For me, this one works:
aws rds describe-db-snapshots \
--query="max_by(DBSnapshots, &SnapshotCreateTime)"
The query parameter returns only the most recent one.
If only the Arn is needed, this one might help:
aws rds describe-db-snapshots \
--query="max_by(DBSnapshots, &SnapshotCreateTime).DBSnapshotArn" \
--output text
And all that for a specific database instance:
aws rds describe-db-snapshots \
--db-instance-identifier={instance identifier} \
--query="max_by(DBSnapshots, &SnapshotCreateTime).DBSnapshotArn" \
--output text
I know this is old, but I was needing to know the same information and was able to construct the following which will then just give me the snapshot name. It doesn't totally answer your question about emphatically finding the latest snapshot but in this example might give you some better direction.
aws rds describe-db-snapshots --db-instance-identifier prd --snapshot-type automated --query "DBSnapshots[?SnapshotCreateTime>='2017-06-05'].DBSnapshotIdentifier"
To break it down with the options
--db-instance-identifier (put in your instance name your are looking for)
--snapshot-type (I put in automated to find the automated backups)
--query "DBSnapshots[?SnapshotCreateTime>='2017-06-05'].DBSnapshotIdentifier"
(This is what I used to refine my search as we do daily backups, I just look for the snapshot create time to be greater than today and by giving the .DBSnapshotIdentifier gives me back just the name.
Hopefully this will help somebody else out.
My way:
> aws rds describe-db-snapshots --db-instance-identifier ${yourDbIdentifier} --query="reverse(sort_by(DBSnapshots, &SnapshotCreateTime))[0]|DBSnapshotIdentifier"
> "rds:dbName-2018-06-20-00-07"
If someone is looking for cluster command:
aws rds describe-db-cluster-snapshots --db-cluster-identifier prod --snapshot-type automated --query "DBClusterSnapshots[?SnapshotCreateTime>='2017-06-05'].DBClusterSnapshotIdentifier"
As at 31th October 2014, it looks like you can use the --t flag to list only automated backups.
http://docs.aws.amazon.com/AmazonRDS/latest/CommandLineReference/CLIReference-cmd-DescribeDBSnapshots.html
From there, you should be able to parse the output to determine your latest snapshots.
rds-describe-db-snapshots --t automated
DBSNAPSHOT rds:<NAME>-2016-08-09-17-12
There is no any other more simple way around for this.
I am getting this error while restoring the db from snapshot with the id that I get with the command from the above methods:
An error occurred (InvalidParameterValue) when calling the RestoreDBInstanceFromDBSnapshot operation: Invalid snapshot identifier: "rds:dev-mysql-rds1-2018-10-06-01-09"
So, I have modified the above query to make it work for me, here is a query that worked for me to get the latest snapshot that worked with restore-db-instance-from-db-snapshot
aws rds describe-db-snapshots --query "DBSnapshots[?DBInstanceIdentifier=='MASTER_INSTANCE_IDENTIFIER']" | jq -r 'max_by(.SnapshotCreateTime).DBSnapshotIdentifier'
aws rds describe-db-cluster-snapshots --snapshot-type=automated --query="max_by(DBClusterSnapshots,&SnapshotCreateTime)"
This works in 2022.08
If it is RDS cluster then you can use below command:
aws rds describe-db-cluster-snapshots --db-cluster-identifier <DBClusterIdentifier> --region <region> --query="max_by(DBClusterSnapshots, &SnapshotCreateTime)"
you can use below command to fetch specific snapshot ARN:
aws rds describe-db-cluster-snapshots --db-cluster-identifier <DBClusterIdentifier> --region <region> --query="max_by(DBClusterSnapshots, &SnapshotCreateTime).DBClusterSnapshotArn"