Select tag of Autoscaling Group inside of instance using AWS CLI - bash

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

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

AWS cli: how to start all machines found by tag

I can list all machines:
aws ec2 describe-instances --filters "Name=tag:Env,Values=my_super_tag" --query 'Reservations[].Instances[].[InstanceId]' --output text
And then I wish to start all found machines - is the aws cli expression what allow that?
The workaround can be applying next aws cli command for received output (machines ids) but here I got the problem too:
$ aws ec2 describe-instances --filters "Name=tag:Env,Values=my_super_tag" --query 'Reservations[].Instances[].[InstanceId]' --output text\
| xargs -L1 aws ec2 start-instances --instance-ids
' does not existd (InvalidInstanceID.NotFound) when calling the StartInstances operation: The instance ID 'i-12345677890
xargs: aws: exited with status 255; aborting
Strange because with echo
aws ec2 describe-instances --filters "Name=tag:Env,Values=spt1" --query 'Reservations[].Instances[].[InstanceId]' --output text | xargs -L 1 echo aws ec2 start-instances --instance-ids
I get output (executing one of below line works as intended)
aws ec2 start-instances --instance-ids i-2123456789
aws ec2 start-instances --instance-ids i-3123456789
aws ec2 start-instances --instance-ids i-4123456789
aws ec2 start-instances --instance-ids i-5123456789
You can embed one command within another, eg:
aws ec2 start-instances --instance-ids `ANOTHER-COMMAND`
So, try this:
aws ec2 start-instances --instance-ids `aws ec2 describe-instances --filters "Name=tag:Env,Values=my_super_tag" --query 'Reservations[].Instances[].InstanceId' --output text`
#John Rotenstein answer do the job, but due to AWS limits and handling already started instances (my question about this link), it's good to add to query
"Name=instance-state-name,Values=stopping,stopped"
So full query then will look like
aws ec2 start-instances --instance-ids `aws ec2 describe-instances --filters "Name=tag:Env,Values=my-super-tag" "Name=instance-state-name,Values=stopping,stopped" --query 'Reservations[].Instances[].InstanceId' --outpu t text`

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