aws ec2 cli + jq exclude results - bash

I'm writing a bash script that needs to get the private ips of all instances where describe-instances does not return platform=>windows, and store them in an array $ips
This script works so far (just getting the private ips)
ips=$(aws ec2 describe-instances --region $r --filters "Name=tag:Name,Values=*$c*" | jq '.Reservations[].Instances[].NetworkInterfaces[].PrivateIpAddress')
but what I can't figure out is how to exclude windows servers (or, conversely, only include non-windows servers)
Here's what I've tried
--filters "Name=tag:Name,Values=*$c*" "Name=platform,Values="
--filters "Name=tag:Name,Values=*$c*" "Name=platform,Values=null"
--filters "Name=tag:Name,Values=*$c*" "Name=platform,Values=NULL"
I've also tried doing it on the jq side of the pipe, but my attempts were ridiculous and I will not publish them here. I did find out you cannot do more than two filters on that side (unless I messed that up too)
Any ideas?

I don't use AWS so I don't have much to go on but based off of the describe-instances reference, I think this filter should work.
.Reservations[].Instances |
map(select(.Platform != "Windows") | .NetworkInterfaces[].PrivateIpAddress)

Related

AWS CLI: How to use variable to filter EFS

I want to use the value of the DOMAIN_ID variable to filter the EFS to get a FileSystemId. I used the commands below. The first command works and it stores the domain ID. The second one returns an empty list, even though the DOMAIN_ID variable is present.
DOMAIN_ID=$(aws sagemaker list-domains --query 'Domains[0].DomainId')
aws efs describe-file-systems --query 'FileSystems[?CreationToken==`$DOMAIN_ID`].FileSystemId'
Output:
[]
Expected output:
<Some EFS identifier>
This works (escaping backticks) -
aws efs describe-file-systems --query "FileSystems[?CreationToken==\`$DOMAIN_ID\`].FileSystemId"
You can also use describe-domain command instead -
$ DOMAIN_ID=$(aws sagemaker list-domains --query 'Domains[0].DomainId' | tr -d '"')
$ aws sagemaker describe-domain --domain-id $DOMAIN_ID --query 'HomeEfsFileSystemId'

Create EC2 instance and get public IP when available

I have a monotonous work of creating an ec2 instance from an AMI and then ssh into it and run a crypto bot to get a sub domain SSL certificates for it and then run some frontend and backend onto it.
I would like to automate this...
I am able to create the EC2 instance
aws ec2 run-instances --image-id ami-0bef9cfcxxxxxx --count 1 --instance-type t2.medium --key-name MyKey --security-group-ids SG-1 --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=SubDomain}]'
but how do I wait till the instance is UP and get the public IP for the next steps?
Any suggestions would help,
Thanks!
Assuming you know the target instance id, you can query your instance and get the current state, instanceId, name (assuming you tagged them with a name) and public IP via something like:
aws ec2 describe-instances \
--instance-ids YOUR_TARGET_INSTANCE_ID \
--query "Reservations[*].Instances[*].[State.Name, InstanceId, Tags[?Key==\`Name\`]|[0].Value, PublicIpAddress]" \
--output text
You could run this query in a loop until the status comes back as running and then capture the public ip address:
while :
do
output=$(aws ec2 describe-instances \
--instance-ids YOUR_TARGET_INSTANCE_ID \
--query "Reservations[*].Instances[*].[State.Name, InstanceId, \
Tags[?Key==\`Name\`]|[0].Value, PublicIpAddress]" \
--output text)
if [[ "${output}" == running* ]] ; then
cut -d $'\t' -f4- <<<"${output}"
break
fi
done
Note:
The aws ec2 queries are all using the default AWS profile. You can specify a different profile via --profile your_target_profile_name if needed.
If you do not know your target instance id, you can remove the --instance-id portion of the aws ec2 query and list all of your instances (in your default region). You could choose the required instance id from that list.

aws-cli --query parameter

I am trying to do a filter using aws query to output 0.0.0.0/0 Ips and find which ports they are coming from however when I do
aws ec2 describe-security-groups --filters Name=ip-permission.cidr,Values='0.0.0.0/0' --query "SecurityGroups[*].{GN:GroupName,Ports: IpPermissions.FromPorts}" --output json
In the Ports column, it outputs None, since it is not finding that filter and when I do
aws ec2 describe-security-groups --filters Name=ip-permission.cidr,Values='0.0.0.0/0' --query "SecurityGroups[*].{GN:GroupName,Ports: IpPermissions}" --output json
I get all the Ip Ranges when I only want 0.0.0.0/0 and which Port that Open Ip is coming from (FromPort and ToPort). And I don't want to do a filter just for a certain Port because I want to see what port each open Ip is coming from.
I am not sure why this is not working since the IpPermissions.ToPort and IpPermissions.FromPort are both a filter of aws security groups.
You need two modification in the query
The key name is FromPort not FromPort
IpPermissions return array not object, so use IpPermissions[].FromPort
aws ec2 describe-security-groups --filters Name=ip-permission.cidr,Values='0.0.0.0/0' \
--query "SecurityGroups[*].{GN:GroupName,Ports: IpPermissions[].FromPort}" --output json

Compare 2 successful results

This results instances listed with ELB:
aws elb describe-load-balancers --load-balancer-name XXXXXXX --region us-east-1 | jq -r '.LoadBalancerDescriptions[].Instances[].InstanceId'
I need some help in writing a script, which checks for new aws instances attached to the ELB.
- Need to compare the present result and previous results, which helps us to get the new instance info.

How do I Copy the same AMI to multiple regions simultaneously?

I am trying to find a way to perform a simultaneously copy of a AMI to all other regions.
I have search near and far but beside seeing on a blog post that it can be done, I haven't found a way using aws cli ...
https://aws.amazon.com/blogs/aws/ec2-ami-copy-between-regions/
Currently I have written a bash script to do so, but I would like to find a better, easier way to do so
I have 8 AMI's that need to be passed to all regions.
using an array-
declare -a DEST=('us-east-1' ...2....3)
aws copy-image --source-region $SRC --region ${DESTx[#]} --source-ami-id $ami
Do you guys have any other suggestion?
Thanks.
you can make a single line bash, specially useful if in future there are new regions:
aws ec2 describe-regions
--output text |\
cut -f 3 | \
xargs -I {} aws copy-image
--source-region $SRC
--region {}
--source-ami-id $ami
basically it goes like this:
aws ec2 describe-regions --output text returns the list of all available regions for ec2, its a 3 columns table ("REGIONS", endpoint, region-name)
cut -f 3 takes the 3rd column of the previous table (read as list)
keep the current region from previous argument (xargs) into {} so you can send it to the region parameter of the copy-image command

Resources