The AWS Command Line Interface is a very powerfull ally to anyone managing AWS Infrastructure.
While automating infrastructure with Terraform, some configuration can be quickly retrieved using AWS CLI.
Alternatively, some information is hard to piece together from the AWS console, in which case terminal scripts can provide fast and simple windows into your cloud.
AWS Documentation gives a good starting point and makes a short reference to the very powerfull JMESPath query language.
On top of the excellent examples provided, below are some of the snippets we tend to fall back on a lot.
Most of the below snippets were first constructed using the slightly more verbose, but more versatile Jq and later optimized to use JMESPath (which often provided faster responses)
This one is mainly used for automation of Terraform configuration
aws iam get-user --output text --query='User.Arn' | grep -Eo '[[:digit:]]{12}'
AWS ElasticBeanstalk uses CloudFormation to provision and tag all resources as well as provides a handy dashboard to manage the overall configuration.
However, some resources are hard to link back to their EB Environment, which the below snippet aims to address.
aws elb describe-load-balancers --query 'LoadBalancerDescriptions[].LoadBalancerName' --output text | xargs -n20 aws elb describe-tags --load-balancer-names --query "TagDescriptions[].[(Tags[?Key=='elasticbeanstalk:environment-name'].Value)[0],LoadBalancerName]" --output text | grep -v None
Notes:
- The
elb describe-tags
did not provide a--filter
option xargs
is used to pass a list of all ELB names (a required parameter to theelb describe-tags
command). A maximum of 20 names can be passed on to this command, which is controlled using thexargs
-n
option.- The first Tag which has a Key of environment name is returned
The below snippet shows each instance registered with a named ELB and if HealthChecks for these instances are passing. Wrapping this in a watch
command will give us a report which is refreshed every second.
export lbname=awseb-e-2-AWSEBL..
watch -n 1 "aws elb describe-instance-health --load-balancer-name $lbname --query 'InstanceStates[].[InstanceId,State]' --output text"
The elb commands to monitor registered instance health do not provide Ip information, when an instance is failing we may want to trouble shoot the instance by accessing it directly. The below watch should allow us to cross reference the InstanceId from the report above.
export env=honestbee
watch -n2 "aws ec2 describe-instances --filters 'Name=\"tag:elasticbeanstalk:environment-name\",Values=\"$env\"' --query 'Reservations[].Instances[].[InstanceId,InstanceType,State.Name,PublicIpAddress]' --output text | sort -k3"
A more generic report of all load balancers and the instances registered with them (using JMESPath to construct new json structures)
aws elb describe-load-balancers --query "LoadBalancerDescriptions[*].{ID:LoadBalancerName,InstanceId:Instances[*].InstanceId}[*]. {ELB:ID,InstanceId:InstanceId[*]}" --output=json
Building on the report above, adding a filter on the number of registered instances to identify ELBs that do not have any Instances registered with them.
This first version uses jq
aws elb describe-load-balancers | jq '.LoadBalancerDescriptions[] | select((.Instances | length) == 0) | .LoadBalancerName'
Show tags for ELBs without instances (without using jq
)
aws elb describe-load-balancers --query "LoadBalancerDescriptions[*].{ID:LoadBalancerName,InstanceId:Instances[*].InstanceId,InstanceCount:length(Instances[*])}[?InstanceCount==\`0\`]. [ID]" --output=text |
while read line
do
aws elb describe-tags --load-balancer-name $line --query "TagDescriptions[*].{ID:LoadBalancerName,Tags:Tags[*]}"
done
In this case, instead of using xargs
a loop is used to get instance tags.
Populate 2 Environment variables from a single query
read DEFAULT_VPC_CIDR DEFAULT_VPC_ID <<<$(aws ec2 describe-vpcs --query 'Vpcs[?IsDefault].[CidrBlock,VpcId]' --output text)
Or construct a json object using JMESPath and Jq:
aws ec2 describe-vpcs --query 'Vpcs[?IsDefault].{id:VpcId,cidr:CidrBlock}[0]' | jq '. | {"default-vpc": . }'
which returns:
{
"default-vpc": {
"cidr": "172.18.0.0/16",
"id": "vpc-3d..."
}
}
Finally, showing more JMESPath functionality to get a comma separated list of Availability zones for a region:
export AWS_REGION=ap-southeast-1
aws ec2 describe-availability-zones --region ${AWS_REGION} --query "AvailabilityZones[*].ZoneName | join(',', @)" --output text
Describe Auto Scaling Actions for an EB Env: