AWS CLI Instance ID in variable - amazon-web-services

Hi can someone help with this
I am using the Amazon AWS CLI command in a bash script and have the following line and the output it gives.
aws ec2 describe-instances --instance-ids $Ins --query 'Reservations[*].Instances[*].[Tags[?Key==`Name`].Value]' --output text
' does not existd (InvalidInstanceID.NotFound) when calling the DescribeInstances operation:
The instance ID 'i-0c7bf4181bdfxxxxx Will be backed up
If I echo the value of $ins and hard code it in the command like
$ echo $Ins
i-0c7bf4181bdfxxxxx
$ aws ec2 describe-instances --instance-ids i-0c7bf4181bdfxxxxx --query 'Reservations[*].Instances[*].[Tags[?Key==`Name`].Value]' --output text
lon-prod-xxxx-xxxx
I don't understand why it works in the command when copied and pasted but not when used as a variable?
Additional Code, sure there are neater ways to do this but just need something quick. Just grabbing all the instance ids from a single VPC and then attempting to take an image of each in turn.
Instances=$(aws ec2 describe-instances --filter "Name=vpc-id,Values=$VPCID" --query 'Reservations[*].Instances[*].[InstanceId]' --output text)
for Ins in $Instances; do
echo $Ins
name=$(aws ec2 describe-instances --instance-ids $Ins --query 'Reservations[*].Instances[*].[Tags[?Key==`Name`].Value]' --output text)
echo $name Will be backed up
echo $Ins
aws ec2 create-image --instance-id $Ins --name "$name" --description "Auto backed up on $(date)" --no-reboot --$dryrun
echo "***"
done
enter code here
error is below, the first id is where i am echoing $Ins so it seems to know the ID, but i think it has a /r /n after it
i-0c7bf4181bdfxxxxx
' does not existd (InvalidInstanceID.NotFound) when calling the DescribeInstances operation:
The instance ID 'i-0c7bf4181bdfxxxxx Will be backed up

OK I fixed it, the variable did have a new line after it "/r"
Added this line
Ins=${Ins/$'\r'/} to strip it out and works OK now.

Related

I have a list of EC2's, and want to loop through the list in bash, does anyone have a way?

I'm using this command "aws ec2 describe-instances --region us-west-2 --filters "Name=instance-state-name,Values=running" --output table --query 'Reservations[].Instances[].InstanceId'". Returns a list of all my running ec2's in us west 2, i'd like to take each output in this list and loop through each one with another command to see which ones are using ssm. Thanks for all responses.
I've tried making an empty array, but that got me no where.
What I've tried, making variable x an empty list
x=[]
and then running the above command to try to have outputs added to empty list x=aws ec2 describe-instances --region us-west-2 --filters "Name=instance-state-name,Values=running" --output table --query 'Reservations[*].Instances[*].InstanceId'. In general I am more familiar with python, but this was just meant to be a quick bash tool.
error: getNonSSMEC2.sh: line 3: ec2: command not found
So firstly - when you want to capture bash command output as a variable you need to declare it like this: x=$(ls) or x=`ls`
Regarding loop:
x=`aws ec2 describe-instances --region us-west-2 --filters "Name=instance-state-name,Values=running" --query 'Reservations[*].Instances[*].InstanceId'`
for id in $(echo $x | jq -r ".[0][0]")
do
echo $id
done
I assume in the loop you should use this function to get SSM informations: https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-instance-information.html
Btw, you can always use describe-instance-information to get list of ec2 instances instead of using ec2 describe-instances.

How to Start AWS instance if it has Tag exists

I would like to run AWS CLI command to start the instance if it has relevant Tags exist for Eg "MigratedBy". If Tag doesnt exists, it shouldnt start the instance at all
I tried running below command but it didnt work out
aws ec2 start-instances --instance-ids `aws ec2 describe-instances --filters "Name=tag:MigratedBy,Values=my-super-tag" --query 'Reservations[].Instances[].InstanceId' --outpu t text`
It seems this command would run all the instance with the tag "MigratedBy" but this is wrong in my case. I would like to just start the particular instance if tag exists otherwise not
If you want to filter based only on the existence of the tag you can include it in the query and then pipe to show only the InstanceId:
aws ec2 describe-instances --query 'Reservations[].Instances[].[Tags[?Key=='MigratedBy'],InstanceId] | [*][1]' --output text
Finally, to start those instances the whole command will be:
aws ec2 start-instances --instance-ids `aws ec2 describe-instances --query 'Reservations[].Instances[].[Tags[?Key=='MigratedBy'],InstanceId] | [*][1]' --output text`
Reference:
Filtering AWS CLI output

Using AWS CLI to stop all instances in a region

How can I use the AWS CLI to stop every EC2 instance in a region (1 VPC)?
I did see an old thread saying that this should work:
aws ec2 stop-instances --instance-ids $(aws ec2 describe-instances --filters "Name=instance-state-name,Values=pending,running" --query "Reservations[].Instances[].[InstanceId]" --output text | tr '\n' ' ')
However, I get the following error when using the above command:
Unknown options: --filters, Name=instance-state-name,Values=pending,running

Terminate a set on EC2 instances by tags using AWS CLI

Faily new to AWS however I am looking to terminate a set of ec2 instances using the AWS CLI by filtering by a Tag name.
If I use describe-instances, I can filter by tag:key=value . For terminate-instances I don't see a way of filtering. I assume this is possible since I can filter and terminate using the AWS console but I am looking to do this via CLI.
Latest AWS CLI allows you to avoid the need for any scripts or jq:
aws ec2 terminate-instances --instance-ids $(aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId' --filters "Name=tag:tagkey,Values=tagvalue" --output text)
as long as the number of expected instances is not huge, the above can be used.
The terminate-instances command only takes a list of instance IDs. You would need to write a script to run the describe-instances command first and capture the instance IDs, then pass those IDs to the terminate-instances command.
I created the following script(.sh) and it worked for me:
aws ec2 describe-instances --query 'Reservations[*].Instances[*].[InstanceId]' --filters 'Name=tag-value,Values=MYTAG' --output text |
grep stopped |
awk '{print $2}' |
while read line;
do aws ec2 terminate-instances --instance-ids $line
done

How to catch AWS EC2 Instance IPs dynamically?

How to catch few AWS EC2 Instances IPs and put them to a script variable if its generates every time randomly and automatically?
I was trying to make it with
echo "$(curl http://169.254.169.254/latest/meta-data/public-ipv4/) master" >> /etc/hosts
but it is just the IP of one of them.
Also was trying with
aws ec2 describe-instances ... but don't know how to separate clear IP with other information. Any suggestions with awk \ sed?
Use the AWS Command-Line Interface (CLI) with a --query parameter:
aws ec2 describe-instances --query 'Reservations[*].Instances[*].{ID:InstanceId,Public:PublicIpAddress,Private:PrivateIpAddress}' --output text
i-2da518a2 172.31.15.3 None
i-6d261640 172.31.27.232 56.64.218.82
i-b3aa3476 172.31.5.0 None
i-6c57c951 172.31.20.243 56.79.129.118
i-192b95c1 172.31.28.76 56.253.207.57
i-af413c91 172.31.27.17 None
You can also output as JSON, which is easier to parse.
End command is
echo "$(aws ec2 describe-instances --filters Name="tag-value",Values="nagios" |grep PrivateIpAddress | awk '{gsub(",","",$2); gsub("\"","",$2); print $2}' | head -n 1) master" >> /file
To catch a dynamic ip address from your aws instance with tag and put it to any file
For example if you want to get all the private IP's which are behind a load balancer and pass it to a file.
/usr/bin/aws --output text --query "Reservations[].Instances[].PrivateIpAddress" ec2 describe-instances --instance-ids aws --output text --query "LoadBalancerDescriptions[0].Instances[*].InstanceId" elb describe-load-balancers --load-balancer-name <loadbalancer name> > hosts.txt
hope it helps....