All AWS node labels (think "table name" in SQL terms) have names that start with Aws
Attributes are mapped from API onto nodes in lowerCamelCase. We try to map as mechanically as possible.
All Aws nodes have attributes: account and region and arn.
Show all AWS-related nodes and relationships in the current graph:
match (a)-[r]-(b) where a.graphEntityGroup='aws'
return distinct labels(a)[0] as fromType, type(r) as relType, labels(b)[0] as toType
order by fromType,toType
If you want to see the relationships for only a specific type, you can restrict one side of the match expression. In this case we want to see all the relationships that EC2 instances have in our graph:
match (a:AwsEc2Instance)-[r]-(b) return distinct labels(a), type(r), labels(b)
If you want to see counts of each node type:
match (a) where a.graphEntityGroup='aws' return distinct labels(a)[0] as label, count(a) as count
The following will show all accounts, VPCs, and subnets:
match (r:AwsAccountRegion)--(v:AwsVpc)--(s:AwsSubnet)
return v.account as account,v.vpcId as vpcId, v.`tag_Name` as vpcName,
s.availabilityZone as availabilityZone,
s.`tag_Name` as subnetName, s.cidrBlock as cidrBlock
To take a look at EC2 instances, we can match on AwsEc2Instance. Since there may be a large number of results we can use the "LIMIT" expression:
match (a:AwsEc2Instance) return a LIMIT 5
To restrict the results by attribute, use a match expression. In this case we match where instanceType is m5.large:
match (a:AwsEc2Instance {instanceType:"m5.large"}) return a
This is equivalent to the following in the where clause. In complex queries, the previous form is preferred.
match (a:AwsEc2Instance) where a.instanceType="m5.large" return a
Regex searching by attribute can be helpful, for instance to match all t2 family instances:
match (a:AwsEc2Instance) where a.instanceType =~ 't2.*' return a
Distinct expression allows for groups to be counted. Here we count the instance types:
match (a:AwsEc2Instance) return distinct a.account,
a.region, a.instanceType, count(a) as count
Here we count family usage. Since family is not an attribute (maybe it should be), we just take the first two characters of the instance type:
match (a:AwsEc2Instance) return distinct a.account, a.region,
substring(a.instanceType,0,2) as instanceFamily, count(a) as count
Counts of AMI in use:
match (a:AwsEc2Instance)--(b:AwsAmi) return distinct b.imageId as imageId,
b.region as region, b.creationDate as creationDate, count(a) as instanceCount
Tags are represented as attributes prefixed with tag_. If the attribute has any non-alphanumeric characters, it needs to be escaped with backticks. Here we look for all EC2 instances that have the tag: aws:autoscaling:groupName:
match (e:AwsEc2Instance)--(s:AwsSubnet)--(v:AwsVpc) where
exists (e.`tag_aws:autoscaling:groupName`)
return v.account,v.`tag_Name` as vpcName ,s.availabilityZone,
e.`tag_Name` as ec2InstanceName, e.publicIpAddress
And inverting the results, we can find all the instances that aren't part of an ASG (do not have the tag aws:autoscaling:groupName):
match (e:AwsEc2Instance)--(s:AwsSubnet)--(v:AwsVpc) where NOT
exists (e.`tag_aws:autoscaling:groupName`)
return v.account,v.`tag_Name` as vpcName ,s.availabilityZone, e.`tag_Name` as ec2InstanceName,
e.publicIpAddress
Similarly we can locate instances that are are part of a cloud formation stack:
match (a:AwsEc2Instance) where exists (a.`tag_aws:cloudformation:stack-id`) return a.region,
a.instanceId, a.`tag_Name` as instanceName,a.`tag_aws:cloudformation:stack-id` as stackId
In Graph View (in Neo4j Browser), to see Account, Region, VPC and Subnets visually.
match (a:AwsAccount)--(ar:AwsAccountRegion)--(v:AwsVpc)--(s:AwsSubnet) return a,ar,v,s LIMIT 100
To add EC2 instances to the preceding query:
match (a:AwsAccount)--(ar:AwsAccountRegion)--(v:AwsVpc)--(s:AwsSubnet)--(i:AwsEc2Instance)
return a,ar,v,s,i LIMIT 100