## AWS EC2 - Inventory Collection
@c:new-block
--> @aws:ec2-instances
--> @dm:save
name = 'cfx-aws-ec2-instances'
--> @c:new-block
--> @aws:ec2-instance-types
--> @dm:fixcolumns
--> @dm:save
name = 'cfx-aws-ec2-instance-types'
--> @c:new-block
--> @aws:ec2-volumes
--> @dm:save
name = 'cfx-aws-ec2-volumes'
--> @c:new-block
--> @aws:ec2-vpcs
--> @dm:save
name = 'cfx-aws-ec2-vpcs'
--> @c:new-block
--> @aws:efs-file-systems
--> @dm:fixcolumns
--> @dm:save
name = 'cfx-aws-ec2-efs-filesystems'
--> @c:new-block
--> @aws:ec2-security-groups
--> @dm:fixcolumns
--> @dm:save
name = 'cfx-aws-ec2-security-groups'
--> @c:new-block
--> @aws:ec2-subnets
--> @dm:fixcolumns
--> @dm:save
name = 'cfx-aws-ec2-subnets'
--> @c:new-block
--> @aws:ec2-internet-gateways
--> @dm:fixcolumns
--> @dm:save
name = 'cfx-aws-ec2-internet-gateways'
## AWS EC2 - Security Groups
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-security-groups'
--> *dm:filter
type = 'Inbound' get account_id as 'aws_account_id',GroupId as 'ec2_inst_sec_group_id',GroupName as 'ec2_inst_sec_group',VpcId as 'ec2_inst_vpc',type as 'ec2_network_direction',IpProtocol as 'ec2_ip_protocol',FromPort as 'ec2_from_port',ToPort as 'ec2_to_port',CidrIp as 'ec2_allowed_source_cidr',region as 'ec2_inst_region',region_name as 'ec2_inst_region_label'
--> @dm:map
from = 'ec2_from_port,ec2_to_port' & to = 'ec2_port_mapping'
--> @dm:map
attr = 'ec2_port_mapping' & func = 'join' & sep = ' => '
--> @dm:map
attr = 'ec2_ip_protocol' & func = 'evaluate' & expr = "'all' if ec2_ip_protocol == '-1' else ec2_ip_protocol"
--> @dm:map
attr = 'ec2_port_mapping' & func = 'evaluate' & expr = "'None' if ec2_port_mapping == ' => ' else ec2_port_mapping"
--> @dm:implode
key_columns = 'ec2_inst_sec_group,ec2_inst_vpc' & merge_columns = 'ec2_ip_protocol,ec2_port_mapping,ec2_allowed_source_cidr'
--> *dm:filter
* get ec2_inst_sec_group,ec2_inst_vpc,ec2_ip_protocol as 'ec2_ip_protocol_inbound',ec2_port_mapping as 'ec2_port_mapping_inbound',ec2_allowed_source_cidr
--> @dm:save
name = 'temp-aws-ec2-security-groups-inbound'
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-security-groups'
--> *dm:filter
type = 'Outbound' get account_id as 'aws_account_id',GroupId as 'ec2_inst_sec_group_id',GroupName as 'ec2_inst_sec_group',VpcId as 'ec2_inst_vpc',type as 'ec2_network_direction',IpProtocol as 'ec2_ip_protocol',FromPort as 'ec2_from_port',ToPort as 'ec2_to_port',CidrIp as 'ec2_allowed_source_cidr',region as 'ec2_inst_region',region_name as 'ec2_inst_region_label'
--> @dm:map
from = 'ec2_from_port,ec2_to_port' & to = 'ec2_port_mapping'
--> @dm:map
attr = 'ec2_port_mapping' & func = 'join' & sep = ' => '
--> @dm:map
attr = 'ec2_ip_protocol' & func = 'evaluate' & expr = "'all' if ec2_ip_protocol == '-1' else ec2_ip_protocol"
--> @dm:map
attr = 'ec2_port_mapping' & func = 'evaluate' & expr = "'None' if ec2_port_mapping == ' => ' else ec2_port_mapping"
--> @dm:implode
key_columns = 'ec2_inst_sec_group,ec2_inst_vpc' & merge_columns = 'ec2_ip_protocol,ec2_port_mapping,ec2_allowed_source_cidr'
--> *dm:filter
* get ec2_inst_sec_group,ec2_inst_vpc,ec2_ip_protocol as 'ec2_ip_protocol_outbound',ec2_port_mapping as 'ec2_port_mapping_outbound',ec2_allowed_source_cidr as 'ec2_allowed_destination_cidr'
--> @dm:save
name = 'temp-aws-ec2-security-groups-outbound'
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-security-groups'
--> *dm:filter
* get account_id as 'aws_account_id',GroupId as 'ec2_inst_sec_group_id',GroupName as 'ec2_inst_sec_group',VpcId as 'ec2_inst_vpc',region as 'ec2_inst_region',region_name as 'ec2_inst_region_label'
--> @dm:enrich
dict = 'temp-aws-ec2-security-groups-inbound' & src_key_cols = 'ec2_inst_sec_group,ec2_inst_vpc' & dict_key_cols = 'ec2_inst_sec_group,ec2_inst_vpc' & enrich_cols = 'ec2_ip_protocol_inbound,ec2_port_mapping_inbound,ec2_allowed_source_cidr'
--> @dm:enrich
dict = 'temp-aws-ec2-security-groups-outbound' & src_key_cols = 'ec2_inst_sec_group,ec2_inst_vpc' & dict_key_cols = 'ec2_inst_sec_group,ec2_inst_vpc' & enrich_cols = 'ec2_ip_protocol_outbound,ec2_port_mapping_outbound,ec2_allowed_destination_cidr'
--> @dm:map
to = 'layer' & func = 'fixed' & value = 'Network'
--> @dm:map
to = 'node_type' & func = 'fixed' & value = 'Firewall'
--> @dm:map
from = 'ec2_inst_sec_group' & to = 'node_label'
--> @dm:map
from = 'ec2_inst_sec_group_id' & to = 'node_id'
--> @dm:save
name = 'cfx-aws-ec2-security-group-nodes'
## AWS EC2 - Nodes
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-instances'
--> @dm:fixcolumns
--> *dm:filter
* get InstanceId as 'ec2_inst_id',State_Name as 'ec2_inst_state',StateReason_Message as 'ec2_inst_state_message',InstanceType as 'ec2_inst_type',RootDeviceName as 'ec2_inst_root_dev',RootDeviceType as 'ec2_inst_root_dev_type',KeyName as 'ec2_inst_keyname',PrivateDnsName as 'ec2_inst_priv_dns',PrivateIpAddress as 'ec2_inst_priv_ip',PublicDnsName as 'ec2_inst_pub_dns',PublicIpAddress as 'ec2_inst_pub_ip',SecurityGroups as 'ec2_inst_sec_group',SubnetId as 'ec2_inst_subnet',VpcId as 'ec2_inst_vpc',Placement_AvailabilityZone as 'ec2_avail_zone',region as 'ec2_inst_region',region_name as 'ec2_inst_region_label',account_id as 'aws_account_id'
--> @dm:enrich
dict = 'cfx-aws-ec2-instance-types' & src_key_cols = 'ec2_inst_type' & dict_key_cols = 'InstanceType' & enrich_cols = 'VCpuInfo_DefaultCores,VCpuInfo_DefaultThreadsPerCore,VCpuInfo_DefaultVCpus,MemoryInfo_SizeInMiB,NetworkInfo_NetworkPerformance' & enrich_cols_as = 'ec2_inst_cpu_sockets,ec2_inst_cpu_cores,ec2_inst_vcpus,ec2_inst_memory_mb,ec2_inst_net_speed'
--> @dm:selectcolumns
exclude='InstanceType'
--> @dm:map
to = 'layer' & func = 'fixed' & value = 'Virtualization'
--> @dm:map
to = 'node_type' & func = 'fixed' & value = 'VM'
--> @dm:map
from = 'ec2_inst_tag_name' & to = 'node_label'
--> @dm:map
from = 'ec2_inst_id' & to = 'node_id'
--> @dm:explode
column = 'ec2_inst_sec_group'
--> @dm:enrich
dict = 'cfx-aws-ec2-security-group-nodes' & src_key_cols = 'ec2_inst_sec_group,ec2_inst_vpc,ec2_inst_region' & dict_key_cols = 'ec2_inst_sec_group,ec2_inst_vpc,ec2_inst_region' & enrich_cols = 'ec2_inst_sec_group_id'
--> @dm:save
name = 'cfx-aws-ec2-instance-nodes'
## AWS EC2 - Disk Volumes
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-volumes'
--> *dm:filter
State = 'in-use' get attached_InstanceIds as 'ec2_inst_id',attached_Devices as 'ec2_disk_id',VolumeId as 'ec2_volume_id',VolumeType as 'ec2_volume_type',State as 'ec2_volume_status',Encrypted as 'ec2_volume_encryption',Iops as 'ec2_volume_iops',Size as 'ec2_volume_size_gb'
--> @dm:map
to = 'layer' & func = 'fixed' & value = 'Virtualization'
--> @dm:map
to = 'node_type' & func = 'fixed' & value = 'vDisk'
--> @dm:map
from = 'ec2_disk_id' & to = 'node_label'
--> @dm:map
from = 'ec2_volume_id' & to = 'node_id'
--> @dm:save
name = 'cfx-aws-ec2-volume-nodes'
## AWS EC2 - VPC
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-subnets'
--> *dm:filter
* get VpcId as 'ec2_inst_vpc',AvailabilityZone as 'ec2_avail_zone'
--> @dm:implode
key_columns = 'ec2_inst_vpc' & merge_columns = 'ec2_avail_zone'
--> @dm:save
name = 'temp-ec2_vpc_az_dist'
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-vpcs'
--> *dm:filter
* get VpcId as 'ec2_inst_vpc',IsDefault as 'ec2_default_vpc',Tags as 'ec2_vpc_tags',account_id as 'aws_account_id',region as 'ec2_inst_region',region_name as 'ec2_inst_region_label'
--> @dm:enrich
dict = 'temp-ec2_vpc_az_dist' & src_key_cols = 'ec2_inst_vpc' & dict_key_cols = 'ec2_inst_vpc' & enrich_cols = 'ec2_avail_zone'
--> @dm:map
to = 'layer' & func = 'fixed' & value = 'Virtualization'
--> @dm:map
to = 'node_type' & func = 'fixed' & value = 'VPC'
--> @dm:map
from = 'ec2_inst_vpc' & to = 'node_label'
--> @dm:map
from = 'ec2_inst_vpc' & to = 'node_id'
--> @dm:save
name = 'cfx-aws-ec2-vpc-nodes'
## AWS EC2 - Internet Gateway
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-internet-gateways'
--> *dm:filter
* get InternetGatewayId as 'ec2_internet_gw_id',account_id as 'aws_account_id',Tags as 'ec2_internet_gw_tags',available_VpcId as 'ec2_inst_vpc',region as 'ec2_inst_region',region_name as 'ec2_inst_region_label'
--> @dm:map
to = 'layer' & func = 'fixed' & value = 'Network'
--> @dm:map
to = 'node_type' & func = 'fixed' & value = 'Router'
--> @dm:map
from = 'ec2_internet_gw_id' & to = 'node_label'
--> @dm:map
from = 'ec2_internet_gw_id' & to = 'node_id'
--> @dm:save
name = 'cfx-aws-ec2-internet-gw-nodes'
## AWS EC2 - Availability Zones
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-vpc-nodes'
--> *dm:filter
* get ec2_avail_zone,ec2_inst_region,ec2_inst_region_label
--> @dm:explode
column = 'ec2_avail_zone'
--> *dm:filter
ec2_avail_zone is not empty
--> @dm:map
to = 'layer' & func = 'fixed' & value = 'Virtualization'
--> @dm:map
to = 'node_type' & func = 'fixed' & value = 'AvailabilityZone'
--> @dm:map
from = 'ec2_avail_zone' & to = 'node_label'
--> @dm:map
from = 'ec2_avail_zone' & to = 'node_id'
--> @dm:save
name = 'cfx-aws-ec2-az-nodes'
## AWS EC2 - Regions
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-vpc-nodes'
--> *dm:filter
* get ec2_inst_region,ec2_inst_region_label
--> @dm:map
to = 'layer' & func = 'fixed' & value = 'Virtualization'
--> @dm:map
to = 'node_type' & func = 'fixed' & value = 'Region'
--> @dm:map
from = 'ec2_inst_region_label' & to = 'node_label'
--> @dm:map
from = 'ec2_inst_region' & to = 'node_id'
--> @dm:save
name = 'cfx-aws-ec2-region-nodes'
## AWS EC2 - EFS Filesystems
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-efs-filesystems'
--> *dm:filter
* get FileSystemId as 'ec2_efs_vol_id',Name as 'ec2_efs_vol_name',SizeInBytes_Value as 'ec2_efs_vol_size_bytes',PerformanceMode as 'ec2_efs_perf_mode',MountTargets_IpAddress as 'ec2_efs_target_ip',MountTargets_NetworkInterfaceId as 'ec2_efs_target_vnic',MountTargets_SubnetId as 'ec2_efs_target_subnetid',MountTargets_VpcId as 'ec2_efs_target_vpc',MountTargets_AvailabilityZoneName as 'ec2_efs_avail_zone',region as 'ec2_efs_region',region_name as 'ec2_efs_region_label'
--> @dm:map
to = 'ec2_efs_vol_size_mb' & func = 'evaluate' & expr = "round(ec2_efs_vol_size_bytes / 1024 / 1024, 2)"
--> @dm:map
to = 'layer' & func = 'fixed' & value = 'Storage'
--> @dm:map
to = 'node_type' & func = 'fixed' & value = 'Volume'
--> @dm:map
from = 'ec2_efs_vol_name' & to = 'node_label'
--> @dm:map
from = 'ec2_efs_vol_id' & to = 'node_id'
--> @dm:save
name = 'cfx-aws-ec2-efs-nodes'
## AWS EC2 Nodes Consolidated Output
--> @c:new-block
--> @dm:concat
names = '^cfx-aws-ec2-instance-nodes$|^cfx-aws-ec2-az-nodes$|^cfx-aws-ec2-region-nodes$|^cfx-aws-ec2-vpc-nodes$|^cfx-aws-ec2-volume-nodes$|^cfx-aws-ec2-efs-nodes$|^cfx-aws-ec2-internet-gw-nodes$|^cfx-aws-ec2-security-group-nodes$'
--> @dm:save
name = 'cfx-aws-ec2-nodes-table-before-dedup'
--> @dm:dedup
--> @dm:save
name = 'cfx-aws-ec2-nodes-table'
## AWS EC2 Relationships
## AWS EC2 to VPC Relationship
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-nodes-table-before-dedup'
--> @dm:map
to = 'relation_type' & func = 'fixed' & value = 'contains'
--> *dm:filter
node_type = 'VM' get ec2_inst_vpc as 'left',relation_type,ec2_inst_id as 'right'
--> @dm:save
name = 'cfx-aws-ec2-vpc-relatioship'
## AWS EC2 to Security-Group Relationship
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-nodes-table-before-dedup'
--> @dm:map
to = 'relation_type' & func = 'fixed' & value = 'used-by'
--> *dm:filter
node_type = 'VM' get ec2_inst_sec_group_id as 'left',relation_type,ec2_inst_id as 'right'
--> @dm:save
name = 'cfx-aws-ec2-sg-relatioship'
## AWS Security-Group to VPC Relationship
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-nodes-table-before-dedup'
--> @dm:map
to = 'relation_type' & func = 'fixed' & value = 'contains'
--> *dm:filter
node_type = 'VM' get ec2_inst_vpc as 'left',relation_type,ec2_inst_sec_group_id as 'right'
--> @dm:save
name = 'cfx-aws-sg-to-vpc-relatioship'
## AWS VPC to Internet Gateway Relationship
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-nodes-table-before-dedup'
--> @dm:map
to = 'relation_type' & func = 'fixed' & value = 'connects-to'
--> *dm:filter
node_type = 'Router' get ec2_internet_gw_id as 'left',relation_type,ec2_inst_vpc as 'right'
--> @dm:save
name = 'cfx-aws-vpc-internet-gw-relatioship'
## AWS VPC to AvailabilityZone Relationship
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-nodes-table-before-dedup'
--> *dm:filter
node_type = 'VPC' get ec2_avail_zone,ec2_inst_vpc
--> @dm:explode
column = 'ec2_avail_zone'
--> @dm:map
to = 'relation_type' & func = 'fixed' & value = 'contains'
--> *dm:filter
* get ec2_avail_zone as 'left',relation_type,ec2_inst_vpc as 'right'
--> @dm:save
name = 'cfx-aws-vpc-az-relatioship'
## AWS AvailabilityZone to Region Relationship
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-nodes-table-before-dedup'
--> *dm:filter
node_type = 'VPC' get ec2_avail_zone,ec2_inst_region
--> @dm:explode
column = 'ec2_avail_zone'
--> @dm:map
to = 'relation_type' & func = 'fixed' & value = 'contains'
--> *dm:filter
* get ec2_inst_region as 'left',relation_type,ec2_avail_zone as 'right'
--> *dm:filter
right is not empty
--> @dm:save
name = 'cfx-aws-az-region-relatioship'
## AWS EC2 Instances to Volume Relationship
--> @c:new-block
--> @dm:recall
name = 'cfx-aws-ec2-nodes-table-before-dedup'
--> @dm:map
to = 'relation_type' & func = 'fixed' & value = 'used-by'
--> *dm:filter
node_type = 'vDisk' get node_id as 'left',relation_type,ec2_inst_id as 'right'
--> @dm:save
name = 'cfx-aws-ec2-volume-relatioship'
## AWS EC2 Nodes Relationship Consolidated Output
--> @c:new-block
--> @dm:concat
names = '^cfx-aws-ec2-vpc-relatioship$|^cfx-aws-vpc-az-relatioship$|^cfx-aws-az-region-relatioship$|^cfx-aws-ec2-volume-relatioship$|^cfx-aws-vpc-internet-gw-relatioship$|^cfx-aws-ec2-sg-relatioship$|^cfx-aws-sg-to-vpc-relatioship$'
--> @dm:dedup
--> @dm:map
from = 'left' & to = 'left_id'
--> @dm:map
from = 'right' & to = 'right_id'
--> @dm:save
name = 'cfx-aws-ec2-relationship-table'
## #########################################
## # AWS EC2 Stacks - Topology Pipeline
## #########################################
--> @c:new-block
--> @dm:stack-create
topology_nodes="cfx-aws-ec2-nodes-table" and topology_edges="cfx-aws-ec2-relationship-table" and name = "aws_ec2_stack"
--> @dm:stack-save
name="AWS EC2 Dependency Map"