OR logic filtering in AWSCLI - amazon-web-services

Im trying to get a list of instances from AWS (using AWSCLI) with tag:env=stage OR tag:backup=true.
i have 1 instance with tag backup=true
i have 5 instance with tag env=stage
i expect to get a list of 6 items
examples :
# returns no instances since its doing AND logic which is fine
aws ec2 describe-instances \
--filters "Name=tag:env,Values=stage" "Name=tag:backup,Values=true" \
--query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value,InstanceId][][]' | tr -d '[]"'
# returns only the last condition ( 1 instance )
aws ec2 describe-instances \
--filters "Name=tag:env,Values=stage" \
--filters "Name=tag:backup,Values=true" \
--query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value,InstanceId][][]' | tr -d '[]"'
# returns only the last condition ( 5 instances )
aws ec2 describe-instances \
--filters "Name=tag:backup,Values=true" \
--filters "Name=tag:env,Values=stage" \
--query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value,InstanceId][][]' | tr -d '[]"'

Related

How can i retrieve the instance id of an instance that is part of an auto scaling group?

I have this bash script that is trying to return the stopped instance Ids of an autoscaling group.
aws ec2 describe-instances --filter "Name=tag:aws:autoscaling:groupName,Values=devASG-123" --query "Reservations[].Instances[?State.Name==stopped].InstanceId" --output text --profile dev
This keeps returning a blank value even though I have instances that are stopped
How can i fix this?
Try this:
aws --profile dev ec2 describe-instances --filters \
"Name=tag:aws:autoscaling:groupName,Values=devASG-123" \
"Name=instance-state-name,Values=stopped" \
--query "Reservations[*].Instances[*].InstanceId
or use regex
aws --profile dev ec2 describe-instances --filters \
"Name=tag:aws:autoscaling:groupName,Values=devASG-123" \
"Name=instance-state-name,Values=stopped" | \
grep -o '\"i-[0-9a-f]\\+\"' | grep -o '[^\"]\\+'

How can list AWS ENI's with a certain "Description" with AWS cli?

When I execute:
aws ec2 describe-network-interfaces --region=us-east-1 \
--query="NetworkInterfaces[*].[Description, NetworkInterfaceId]" \
--output text \
--filter 'Name=Description,Values=ELB*'
I get this error message:
An error occurred (InvalidParameterValue) when calling the DescribeNetworkInterfaces operation:
The filter 'Description' is invalid
I am trying to list my ENI's that have a description that starts with "ELB".
UPDATE: Thanks jordanm your suggestion has stopped the error message but I still think I doing something wrong with my filter option. If I execute:
aws ec2 describe-network-interfaces --region=us-east-1 \
--query="NetworkInterfaces[*].[Description, NetworkInterfaceId]" \
--output text | grep "^ELB"
I get results, but if I try to filter with --filter 'Name=Description,Values=ELB*' instead of | grep "^ELB" I do not get any results.
The following should get you ENI's whose description begin with 'EBS'
aws ec2 describe-network-interfaces --region=us-east-1 \
--query="NetworkInterfaces[?starts_with(Description, 'EBS')].[Description, NetworkInterfaceId]" \
--output text
You can change the literal 'EBS' to whatever value you want to check for in the description. If you want to do a check where the Description contains 'EBS' not just begins with it, you can use the following command
aws ec2 describe-network-interfaces --region=us-east-1 \
--query="NetworkInterfaces[?contains(Description, 'EBS')].[Description, NetworkInterfaceId]" \
--output text

How do I specify multiple filters to aws ec2 describe-vpc-peering-connections?

I am trying to get a list of 'active' peering connections via aws ec2 ec2 describe-vpc-peering-connections. Here is what I have tried:
aws ec2 describe-vpc-peering-connections --region=eu-west-3 \
--filter 'Name=accepter-vpc-info.vpc-id,Values=vpc-xxxxxx Name=status-code,Values=active' \
--query 'VpcPeeringConnections[*].VpcPeeringConnectionId' --output text
But I get the error:
Error parsing parameter '--filters': Second instance of key "Values" encountered for input:
Name=accepter-vpc-info.vpc-id,Values=vpc-xxxxxxxx Name=status-code,Values=active
^
This is often because there is a preceeding "," instead of a space.
I think I need the , right? Is there something else I am getting wrong?
aws ec2 describe-vpc-peering-connections \
--region=eu-west-3 \
--filter Name=accepter-vpc-info.vpc-id,Values=vpc-xxxxxx \
--filter Name=status-code,Values=active \
--query 'VpcPeeringConnections[*].VpcPeeringConnectionId' \
--output text
OR
aws ec2 describe-vpc-peering-connections \
--region=eu-west-3 \
--filter 'Name=accepter-vpc-info.vpc-id,Values=vpc-xxxxxx' \
'Name=status-code,Values=active' \
--query 'VpcPeeringConnections[*].VpcPeeringConnectionId' \
--output text
Combining server-side and client-side filtering

How to sort results from `list-tasks` in aws-cli?

I have few tasks running i want to get the latest(task which started last, with last created-at) task arn.
I am using this command
aws ecs list-tasks --cluster {cluster} --family {family} --desired-status 'STOPPED'
after exploring a little i got to know about sort_by. I tried
aws ecs list-tasks --cluster {cluster} --family {family} --desired-status 'STOPPED' --query "sort_by(taskArns, &CreatedAt)"
But this gives error
In function sort_by(), invalid type for value: <some_task_arn>, expected one of: ['string', 'number'], received: "null"
list-tasks will not give you that information. Have to use both list-tasks and describe-tasks.
I will provide example on my cluster, with RUNNING state tasks. You will have to adjust it to your need.
1. Get the list of tasks
task_arns=$(aws ecs list-tasks --cluster ${cluster[Name]} \
--desired-status 'RUNNING' \
--query 'taskArns' --output text)
echo ${task_arns}
Should give a list of Arns of your tasks, e.g.:
arn:aws:ecs:us-east-1:275795381673:task/0053c603-a6c9-4044-89f5-b0edc8f6de3f arn:aws:ecs:us-east-1:275795381673:task/0b4626ea-0f2b-4c99-9e90-010e8a0c8ad3 arn:aws:ecs:us-east-1:275795381673:task/0d4aa5f2-f547-45ad-b1f8-ed84ef1d678c arn:aws:ecs:us-east-1:275795381673:task/190a320f-4b68-497a-921e-439460447d45 arn:aws:ecs:us-east-1:275795381673:task/c979f4a2-3665-4c56-93c6-e9b88f6b3519
2. Get sorted tasks Arns
aws ecs describe-tasks --cluster ${cluster[Name]} \
--tasks ${task_arns} \
--query "tasks[] | reverse(sort_by(#, &createdAt)) | [].[createdAt,taskArn]" \
--output table
Should give, eg:
----------------------------------------------------------------------------------------------------
| DescribeTasks |
+----------------+---------------------------------------------------------------------------------+
| 1589888493.15 | arn:aws:ecs:us-east-1:275795381673:task/c979f4a2-3665-4c56-93c6-e9b88f6b3519 |
| 1589888501.348| arn:aws:ecs:us-east-1:275795381673:task/190a320f-4b68-497a-921e-439460447d45 |
| 1589888499.438| arn:aws:ecs:us-east-1:275795381673:task/0d4aa5f2-f547-45ad-b1f8-ed84ef1d678c |
| 1589888500.312| arn:aws:ecs:us-east-1:275795381673:task/0b4626ea-0f2b-4c99-9e90-010e8a0c8ad3 |
| 1589888497.701| arn:aws:ecs:us-east-1:275795381673:task/0053c603-a6c9-4044-89f5-b0edc8f6de3f |
+----------------+---------------------------------------------------------------------------------+
3. Get last element sorted tasks Arns
aws ecs describe-tasks --cluster ${cluster[Name]} \
--tasks ${task_arns} \
--query "tasks[] | reverse(sort_by(#, &createdAt)) | [-1].[taskArn]" \
--output text
Should give:
arn:aws:ecs:us-east-1:275795381673:task/0053c603-a6c9-4044-89f5-b0edc8f6de3f
Assuming you work from a Linux/Unix-Shell I would suggest sending the output to the sort command. This works by adding
| sort
to your command at the end of the line:
aws ecs list-tasks --cluster {cluster} --family {family} --desired-status 'STOPPED' | sort
I hope this helps.

Escape correctly long sequence of systemd command

I have the following systemd unit
[Unit]
Description=Tag EBS Volumes without tags with AutoScaling Group tags
[Service]
Type=oneshot
ExecStartPre=/bin/bash -c "/usr/bin/curl -s https://stedolan.github.io/jq/download/linux64/jq > /usr/local/bin/jq && chmod +x /usr/local/bin/jq"
ExecStart=/bin/bash
-c 'AWS_REGION=$(/usr/bin/curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/[a-z]$//'); \
INSTANCE_ID=$(/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id); \
VOLUMES=$(/usr/local/bin/aws ec2 describe-volumes --region $AWS_REGION --filters Name=attachment.instance-id,Values=$INSTANCE_ID | /usr/local/bin/jq -r '"'"'.Volumes[] | select(.Tags == null) | .Attachments[].VolumeId'"'"'); \
AUTOSCALING_GROUP=$(/usr/local/bin/aws autoscaling describe-auto-scaling-instances --region $AWS_REGION --instance-ids $INSTANCE_ID | /usr/local/bin/jq -r .AutoScalingInstances[].AutoScalingGroupName); \
TAGS=$(/usr/local/bin/aws autoscaling describe-tags --region $AWS_REGION --filters Name=auto-scaling-group,Values=$AUTOSCALINGGROUP --query '"'"'Tags[*].{Key:Key,Value:Value}'"'"'); \
/usr/local/bin/aws ec2 create-tags --region "$AWS_REGION" --resources "$VOLUMES" --tags "$TAGS";'
I'd like to ask if you have some recommendations to make it more readable and working. I'm not able to escape correctly the sequence and I get error to execute it.
Dec 16 09:43:36 ip-172-20-39-162 systemd[1]: Started Tag EBS Volumes without tags with AutoScaling Group tags.
Dec 16 10:21:03 ip-172-20-39-162 systemd[1]: [/lib/systemd/system/kops-hook-tag-ebs-volumes.service:11] Unknown lvalue '-c 'AWS_REGION' in section 'Service'
Looking purely at your question, you're missing an escape \ on line
ExecStart=/bin/bash
Should be
ExecStart=/bin/bash \
-c 'AWS_REGION=$(/usr/bin/curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/[a-z]$//'); \
INSTANCE_ID=$(/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id); \
VOLUMES=$(/usr/local/bin/aws ec2 describe-volumes --region $AWS_REGION --filters Name=attachment.instance-id,Values=$INSTANCE_ID | /usr/local/bin/jq -r '"'"'.Volumes[] | select(.Tags == null) | .Attachments[].VolumeId'"'"'); \
AUTOSCALING_GROUP=$(/usr/local/bin/aws autoscaling describe-auto-scaling-instances --region $AWS_REGION --instance-ids $INSTANCE_ID | /usr/local/bin/jq -r .AutoScalingInstances[].AutoScalingGroupName); \
TAGS=$(/usr/local/bin/aws autoscaling describe-tags --region $AWS_REGION --filters Name=auto-scaling-group,Values=$AUTOSCALINGGROUP --query '"'"'Tags[*].{Key:Key,Value:Value}'"'"'); \
/usr/local/bin/aws ec2 create-tags --region "$AWS_REGION" --resources "$VOLUMES" --tags "$TAGS";'
To simplify things; I would suggest setting your environment variables in ExecStartPre