How to find ami id using shell script - shell

How to find ami id using shell script
My Script :
for i in $(cat /tmp/amidel.txt); do
echo "Image ID of instance which needed to be Deregistered is $i ";
val1="$i"-i-*
aws ec2 describe-images --filters "Name=name,Values=$val1" | awk '{ print $11 }'
done
Now Issue is that "aws ec2 describe-images" returns image id for different awk value :
$ aws ec2 describe-images --filters "Name=name,Values=instance-20Aug15-i-*" | awk '{ print $9 }'
Output :
ami-xxxx
$ aws ec2 describe-images --filters "Name=name,Values=instance-18Aug15-i-*" | awk '{ print $11 }'
Output :
ami-xxxx
This is happening because third value returned by "aws ec2 describe-images" is Comment which varies for each ami image :
$ aws ec2 describe-images --filters "Name=name,Values=instance-18Aug15-i-*"
Output :
IMAGES x86_64 This is for Daily auto AMI creation xen ami-bebfb1ec 008392659736/instance-18Aug15-i-1effb6d3 machine aki-503e7402 instance-18Aug15-i-1effb6d3 008392659736 False /dev/sda1 ebs available paravirtual
BLOCKDEVICEMAPPINGS /dev/sda1
EBS True snap-51539764 8 gp2
BLOCKDEVICEMAPPINGS /dev/sdf
EBS False snap-4e95d37b 20 gp2
For 2nd Ami :
$ aws ec2 describe-images --filters "Name=name,Values=instance-20Aug15-i-*"
Output :
IMAGES x86_64 This is created by ami-backup.sh xen ami-52020b00 008392659736/instance-20Aug15-i-127fb8df machine instance-20Aug15-i-127fb8df 008392659736 False /dev/sda1 ebs simple available hvm
BLOCKDEVICEMAPPINGS /dev/sda1
EBS True snap-2b563aca 8 gp2
So please help me how parse this to get proper ami id or is there any other method to find ami id from ami name ?

awk is an inappropriate tool to parse JSON. jq would be substantially more appropriate if you like chaining tools.
You can change the output format returned by aws-cli. That makes awk/grep more appropriate.
You can also use --query instead of trying to parse it through awk. It uses the JMESPath syntax, which is slightly easier than the jq syntax.
Here's some examples:
$ aws ec2 describe-images --image-ids ami-6b1cd400 --query Images[].ImageId
[
"ami-6b1cd400"
]
$ aws ec2 describe-images --image-ids ami-6b1cd400 --query Images[].ImageId --output text
ami-6b1cd400

We can find AMI id by using AWS CLI and jQuery.
I have managed to solve this with the following command:
aws ec2 describe-images --owners self --output json | jq '.Images[] | {ImageId}' | jq --raw-output '.ImageId'

Related

how to iterate over aws cli result using bash for loop ? [describe-images]

Goal: find specific AMI's and copy them to another AWS region.
using describe-images and its filter i get a list of ImageId and Name,
AMI_LIST=$(aws ec2 describe-images --filters "Name=tag:Name,Values=*one*,*two*,*three*,*four*" \
"Name=state,Values=available" "Name=tag:Name,Values=${CUSTOMER_NAME}*" \
--query 'Images[*].{ID:ImageId,NAME:Name}' --output text)
echo $AMI_LIST
result:
ami-036ba4ef9fa1d148d big394_one_1 ami-06d13684f11138f1f big394_two_3 ami-0706803a11e21946d big394_two_1 ami-094043f896db39243 big394_two_2 ami-0c11ff60c981c2273 big394_three_1 ami-0d0b30fcc69f30af8 big394_four_1
then i want to copy the images to another AWS region using a loop:
for ami in $AMI_LIST; do
aws ec2 copy-image --source-image-id ${ami[0]} --source-region us-east-1 --region us-west-2 --name ${ami[2]}
done
ofc it does not work because ${ami[0]} and ${ami[1]} has no meaning, but they represent what i would like to achieve.
i did try to play with converting the list to array but without success.
Thanks.
This should achieve what you expected :
aws ec2 describe-images --filters "Name=tag:Name,Values=*one*,*two*,*three*,*four*" \
"Name=state,Values=available" "Name=tag:Name,Values=${CUSTOMER_NAME}*" \
--query 'Images[*].{ID:ImageId,NAME:Name}' --output text \
| while read ami name; do
aws ec2 copy-image --source-image-id $ami --source-region us-east-1\
--region us-west-2 --name $name
done

get subnet id AWS

i am trying to get the subnet ids within a particular VPC and store them in variables
so I can use them in a bash script
aws ec2 describe-subnets --filter "Name=vpc-id,Values=VPCid" --region $REGION --query "Subnets[*].SubnetId" --output text
and this gives something like this
subnet-12345 subnet-78910
(END)
I wonder how I can store them into a variable.
I tried with
SBnet=$(aws ec2 describe-subnets --filter "Name=vpc-id,Values=VPCid" --region $REGION --query "Subnets[*].SubnetId" --output text)
but then I do not know I can access the array/list created.
I tried with
echo $(SBnet[0])
but does not work
I am on MACos usin zsh
You can do this as follows (add your VPC and the region):
#!/bin/bash
SUBNET_IDS=$(aws ec2 describe-subnets --filter "Name=vpc-id,Values=vpc-1234" --query "Subnets[*].SubnetId" --output text)
for SUBNET_ID in $SUBNET_IDS;
do
echo $SUBNET_ID
done
To split the list of subnet IDs into variables, you can do this:
#!/bin/bash
SUBNET_IDS=$(aws ec2 describe-subnets --filter "Name=vpc-id,Values=vpc-1234" --query "Subnets[*].SubnetId" --output text)
IFS=$'\t ' read -r -a subnet_ids <<< $SUBNET_IDS
echo "${subnet_ids[0]}"
echo "${subnet_ids[1]}"
And the individual subnet IDs will be in the subnet_ids array.
you can do as #jarmod suggested and you could also write a query to extract all the subnets tied to all the VPC's in your system in a comma separated output and use it further like this
aws ec2 describe-subnets --query "Subnets[].[SubnetId,VpcId,CidrBlock,AvailabilityZone]" --output text|sed 's/\t/,/g'

passing command from awk to the next command using xargs

I am using AWS EC2 CLI to perform a filter on stopped instances, then create an AMI out of these with the AMI name taken from the instance tag.
aws ec2 describe-instances --output text --profile proj --query 'Reservations[*].[Instances[*].[InstanceId, InstanceType, State.Name, Platform, Placement.AvailabilityZone, PublicIpAddress, PrivateIpAddress,[Tags[?Key==`Name`].Value][0][0]]]' --filter --filters Name=instance-state-name,Values=stopped | awk '{print $1, $8}' | xargs -n2 aws ec2 create-image --profile proj --instance-id {} --name {} --no-reboot
how to let args differentiate the two different parameters from AWK (instnaceid, instance name tag), thereby it can be correctly pumped into the ec2 create-image on the instance-id and --name parameter accordingly
You do not need awk.Using AWS CLI, you are extracting 8 values first and then using awk to extract 2 values from that 8 values. Why? Just extract the 2 values from AWS CLI without using awk.
--query 'Reservations[*].[Instances[*].[InstanceId, [Tags[?Key==`Name`].Value][0][0]]]'
will return only the values you are interested in. Then use xargs to pass the arguments to your next command.
xargs -n2 command --arg1 $1 --arg2 $2
Your entire command becomes:
aws ec2 describe-instances --output text --profile proj --query 'Reservations[*].[Instances[*].[InstanceId, [Tags[?Key==`Name`].Value][0][0]]]' --filter --filters Name=instance-state-name,Values=stopped | xargs -n2 aws ec2 create-image --profile proj --instance-id $1 --name $2 --no-reboot

Select tag of Autoscaling Group inside of instance using AWS CLI

When I inside of instance that have Autoscaling Group. I'm trying to select some specific tag of Autoscaling Group. i know that I can use AWS CLI command "aws autoscaling describe-tags".
So I wrote some .sh file. Than contain:
#!/bin/sh
#Instance ID
InstanceID=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id`
#Allocation ID from Autoscaling tags
Autoscaling=`aws ec2 describe-tags --filters "Name=resource-id,Values=$InstanceID" "Name=key,Values=aws:autoscaling:groupName"`
AllocationID=`aws autoscaling describe-tags --filter "Name=key,Values=$Autoscaling"| select(["Value"] | contains("eipalloc"))`
#Assigning VPC Elastic IP to Instance via Allocation ID
aws ec2 associate-address --instance-id $InstanceID --allocation-id $AllocationID
It doesn't work only because I can't select value in this way. Who can tell me how I can properly select some specific tag?
Thanks!
Looks terrible, but it works:
#!/bin/sh
#Instance ID
InstanceID=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id`
#Elastic IP captured through the AllocationID Autoscaling tag
ScalingGroup=`aws ec2 describe-tags --filters "Name=resource-id,Values=$InstanceID" "Name=key,Values=aws:autoscaling:groupName" | jq '.Tags[] | .Value'`
AllocationID=`aws autoscaling describe-tags --filters "Name=auto-scaling-group,Values=$ScalingGroup" | jq '.Tags[] | select(.["Key"] | contains("AllocationID")) | .Value'`
AllocationID=`echo $AllocationID | tr -d '"'`
#Assigning Elastic IP to Instance
aws ec2 associate-address --instance-id $InstanceID --allocation-id $AllocationID

List public IP addresses of EC2 instances

I want to list the public IP addresses of my EC2 instances using Bash, separated by a delimiter (space or a new-line).
I tried to pipe the output to jq with aws ec2 describe-instances | jq, but can't seem to isolate just the IP addresses.
Can this be done by aws alone, specifying arguments to jq, or something else entirely?
Directly from the aws cli:
aws ec2 describe-instances \
--query "Reservations[*].Instances[*].PublicIpAddress" \
--output=text
Filter on running instances (you can drop that part if you don't need it)
Query for each PublicIPaddress and the Name Tag, handling when Name isn't set
aws ec2 describe-instances \
--filter "Name=instance-state-name,Values=running" \
--query "Reservations[*].Instances[*].[PublicIpAddress, Tags[?Key=='Name'].Value|[0]]" \
--output text
The below command would list the IP addresses of all your running EC2 instances
aws ec2 describe-instances | grep PublicIpAddress | grep -o -P "\d+\.\d+\.\d+\.\d+" | grep -v '^10\.'
Hope that answers your query...
But this works without all the errors about access:
wget -qO- http://instance-data/latest/meta-data/public-ipv4/|grep .
You can use instance metadata so you can run the following command from the ec2 instance:
curl http://169.254.169.254/latest/meta-data/public-ipv4
and it will give you the public IP of the instance. If you want the private IP, you will run
curl http://169.254.169.254/latest/meta-data/local-ipv4
aws ec2 describe-instances --query "Reservations[].Instances[][PublicIpAddress]"
Refer:
http://docs.aws.amazon.com/cli/latest/userguide/controlling-output.html

Resources