From 8aea8c35b4de70ba4ee140c0c39cd6298752554f Mon Sep 17 00:00:00 2001 From: Michael Droessler Date: Wed, 11 Aug 2021 16:07:11 -0500 Subject: [PATCH 01/13] wip commit --- pwsh/lw_aws_inventory.ps1 | 150 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 pwsh/lw_aws_inventory.ps1 diff --git a/pwsh/lw_aws_inventory.ps1 b/pwsh/lw_aws_inventory.ps1 new file mode 100644 index 0000000..0c4eaa8 --- /dev/null +++ b/pwsh/lw_aws_inventory.ps1 @@ -0,0 +1,150 @@ +# Script to fetch AWS inventory for Lacework sizing. +# Requirements: awscli + +# You can specify a profile with the -p flag, or get JSON output with the -j flag. +# Note: +# 1. You can specify multiple accounts by passing a comma seperated list, e.g. "default,qa,test", +# there are no spaces between accounts in the list +# 2. The script takes a while to run in large accounts with many resources, the final count is an aggregation of all resources found. + +param +( + [CmdletBinding()] + [bool] $j = $false, + + [CmdletBinding()] + [string] $p = "default" +) + +$AWS_PROFILE=$p + +<# +# Usage: ./lw_aws_inventory.sh +while getopts ":jp:" opt; do + case ${opt} in + p ) + AWS_PROFILE=$OPTARG + ;; + j ) + JSON="true" + ;; + \? ) + echo "Usage: ./lw_aws_inventory.sh [-p profile] [-j]" 1>&2 + exit 1 + ;; + : ) + echo "Usage: ./lw_aws_inventory.sh [-p profile] [-j]" 1>&2 + exit 1 + ;; + esac +done +shift $((OPTIND -1)) +#> + +# Set the initial counts to zero. +$EC2_INSTANCES=0 +$RDS_INSTANCES=0 +$REDSHIFT_CLUSTERS=0 +$ELB_V1=0 +$ELB_V2=0 +$NAT_GATEWAYS=0 + +$TOTAL = 0 + +function getRegions { + $(aws --profile $profile ec2 describe-regions --output json | ConvertFrom-Json).Regions.RegionName +} + +function getInstances { + $(aws --profile $profile ec2 describe-instances --query 'Reservations[*].Instances[*].[InstanceId]' --region $r --output json --no-paginate | ConvertFrom-Json).Count +} + +function getRDSInstances { + $(aws --profile $profile rds describe-db-instances --region $r --output json --no-paginate | ConvertFrom-Json).DBInstances.Count +} + +function getRedshift { + $(aws --profile $profile redshift describe-clusters --region $r --output json --no-paginate | ConvertFrom-Json).Clusters.Count +} + +function getElbv1 { + $(aws --profile $profile elb describe-load-balancers --region $r --output json --no-paginate | ConvertFrom-Json).LoadBalancerDescriptions.Count +} + +function getElbv2 { + $(aws --profile $profile elbv2 describe-load-balancers --region $r --output json --no-paginate | ConvertFrom-Json).LoadBalancers.Count +} + +function getNatGateways { + $(aws --profile $profile ec2 describe-nat-gateways --region $r --output json --no-paginate | ConvertFrom-Json).NatGateways.Count +} + +function calculateInventory { + + param( + $profile + ) + + foreach ($r in $(getRegions)){ + if ($JSON -ne $true){ + Write-Host $r + } + $instances=$(getInstances $r $profile) + $EC2_INSTANCES=$(($EC2_INSTANCES + $instances)) + + $rds=$(getRDSInstances $r $profile) + $RDS_INSTANCES=$(($RDS_INSTANCES + $rds)) + + $redshift=$(getRedshift $r $profile) + $REDSHIFT_CLUSTERS=$(($REDSHIFT_CLUSTERS + $redshift)) + + $elbv1=$(getElbv1 $r $profile) + $ELB_V1=$(($ELB_V1 + $elbv1)) + + $elbv2=$(getElbv2 $r $profile) + $ELB_V2=$(($ELB_V2 + $elbv2)) + + $natgw=$(getNatGateways $r $profile) + $NAT_GATEWAYS=$(($NAT_GATEWAYS + $natgw)) + } + + return $EC2_INSTANCES + $RDS_INSTANCES + $REDSHIFT_CLUSTERS + $ELB_V1 + $ELB_V2 + $NAT_GATEWAYS +} + +function textoutput { + write-host "######################################################################" + write-host "Lacework inventory collection complete." + write-host "" + write-host "EC2 Instances: $EC2_INSTANCES" + write-host "RDS Instances: $RDS_INSTANCES" + write-host "Redshift Clusters: $REDSHIFT_CLUSTERS" + write-host "v1 Load Balancers: $ELB_V1" + write-host "v2 Load Balancers: $ELB_V2" + write-host "NAT Gateways: $NAT_GATEWAYS" + write-host "====================" + write-host "Total Resources: $TOTAL" +} + +function jsonoutput { + write-host "{" + write-host " \"ec2\": \"$EC2_INSTANCES\"," + write-host " \"rds\": \"$RDS_INSTANCES\"," + write-host " \"redshift\": \"$REDSHIFT_CLUSTERS\"," + write-host " \"v1_lb\": \"$ELB_V1\"," + write-host " \"v2_lb\": \"$ELB_V2\"," + write-host " \"nat_gw\": \"$NAT_GATEWAYS\"," + write-host " \"total\": \"$TOTAL\"" + write-host "}" +} + +# TOOD: figure out if we support this? +#foreach ($PROFILE in $(echo $AWS_PROFILE | sed "s/,/ /g")){ +$TOTAL = calculateInventory -profile $PROFILE +#} + +if ($JSON -eq $true){ + write-host $jsonoutput +}else{ + write-host $textoutput +} + From 35d4f975a33afbedb02dfd63311800a9b6027059 Mon Sep 17 00:00:00 2001 From: Michael Droessler Date: Wed, 11 Aug 2021 16:45:35 -0500 Subject: [PATCH 02/13] wip commit 2 --- lw_aws_exploit.sh => bash/lw_aws_exploit.sh | 0 .../lw_aws_inventory.sh | 0 .../lw_aws_preflight.sh | 0 .../lw_azure_inventory.sh | 0 .../lw_gcp_inventory.sh | 0 pwsh/lw_aws_inventory.ps1 | 151 ++++++++++++------ test/todo.txt | 0 7 files changed, 104 insertions(+), 47 deletions(-) rename lw_aws_exploit.sh => bash/lw_aws_exploit.sh (100%) rename lw_aws_inventory.sh => bash/lw_aws_inventory.sh (100%) rename lw_aws_preflight.sh => bash/lw_aws_preflight.sh (100%) rename lw_azure_inventory.sh => bash/lw_azure_inventory.sh (100%) rename lw_gcp_inventory.sh => bash/lw_gcp_inventory.sh (100%) create mode 100644 test/todo.txt diff --git a/lw_aws_exploit.sh b/bash/lw_aws_exploit.sh similarity index 100% rename from lw_aws_exploit.sh rename to bash/lw_aws_exploit.sh diff --git a/lw_aws_inventory.sh b/bash/lw_aws_inventory.sh similarity index 100% rename from lw_aws_inventory.sh rename to bash/lw_aws_inventory.sh diff --git a/lw_aws_preflight.sh b/bash/lw_aws_preflight.sh similarity index 100% rename from lw_aws_preflight.sh rename to bash/lw_aws_preflight.sh diff --git a/lw_azure_inventory.sh b/bash/lw_azure_inventory.sh similarity index 100% rename from lw_azure_inventory.sh rename to bash/lw_azure_inventory.sh diff --git a/lw_gcp_inventory.sh b/bash/lw_gcp_inventory.sh similarity index 100% rename from lw_gcp_inventory.sh rename to bash/lw_gcp_inventory.sh diff --git a/pwsh/lw_aws_inventory.ps1 b/pwsh/lw_aws_inventory.ps1 index 0c4eaa8..098e1cd 100644 --- a/pwsh/lw_aws_inventory.ps1 +++ b/pwsh/lw_aws_inventory.ps1 @@ -13,7 +13,11 @@ param [bool] $j = $false, [CmdletBinding()] - [string] $p = "default" + [string] $p = "default", + + # enable verbose output + [CmdletBinding()] + [bool] $v = $false ) $AWS_PROFILE=$p @@ -42,41 +46,75 @@ shift $((OPTIND -1)) #> # Set the initial counts to zero. -$EC2_INSTANCES=0 -$RDS_INSTANCES=0 -$REDSHIFT_CLUSTERS=0 -$ELB_V1=0 -$ELB_V2=0 -$NAT_GATEWAYS=0 +$global:EC2_INSTANCES=0 +$global:RDS_INSTANCES=0 +$global:REDSHIFT_CLUSTERS=0 +$global:ELB_V1=0 +$global:ELB_V2=0 +$global:NAT_GATEWAYS=0 $TOTAL = 0 function getRegions { - $(aws --profile $profile ec2 describe-regions --output json | ConvertFrom-Json).Regions.RegionName + param( + $profile + ) + + $(aws --profile $profile ec2 describe-regions --output json | ConvertFrom-Json).Regions.RegionName } function getInstances { - $(aws --profile $profile ec2 describe-instances --query 'Reservations[*].Instances[*].[InstanceId]' --region $r --output json --no-paginate | ConvertFrom-Json).Count + param( + $profile, + $region + ) + + $(aws --profile $profile ec2 describe-instances --query 'Reservations[*].Instances[*].[InstanceId]' --region $region --output json --no-paginate | ConvertFrom-Json).Count } function getRDSInstances { - $(aws --profile $profile rds describe-db-instances --region $r --output json --no-paginate | ConvertFrom-Json).DBInstances.Count + param( + $profile, + $region + ) + + $(aws --profile $profile rds describe-db-instances --region $region --output json --no-paginate | ConvertFrom-Json).DBInstances.Count } function getRedshift { - $(aws --profile $profile redshift describe-clusters --region $r --output json --no-paginate | ConvertFrom-Json).Clusters.Count + param( + $profile, + $region + ) + + $(aws --profile $profile redshift describe-clusters --region $region --output json --no-paginate | ConvertFrom-Json).Clusters.Count } function getElbv1 { - $(aws --profile $profile elb describe-load-balancers --region $r --output json --no-paginate | ConvertFrom-Json).LoadBalancerDescriptions.Count + param( + $profile, + $region + ) + + $(aws --profile $profile elb describe-load-balancers --region $region --output json --no-paginate | ConvertFrom-Json).LoadBalancerDescriptions.Count } function getElbv2 { - $(aws --profile $profile elbv2 describe-load-balancers --region $r --output json --no-paginate | ConvertFrom-Json).LoadBalancers.Count + param( + $profile, + $region + ) + + $(aws --profile $profile elbv2 describe-load-balancers --region $region --output json --no-paginate | ConvertFrom-Json).LoadBalancers.Count } function getNatGateways { - $(aws --profile $profile ec2 describe-nat-gateways --region $r --output json --no-paginate | ConvertFrom-Json).NatGateways.Count + param( + $profile, + $region + ) + + $(aws --profile $profile ec2 describe-nat-gateways --region $region --output json --no-paginate | ConvertFrom-Json).NatGateways.Count } function calculateInventory { @@ -85,66 +123,85 @@ function calculateInventory { $profile ) - foreach ($r in $(getRegions)){ + foreach ($r in $(getRegions -profile $profile)){ if ($JSON -ne $true){ - Write-Host $r + #Write-Host $r + } + + $instances=$(getInstances -region $r -profile $profile) + $global:EC2_INSTANCES=$(($global:EC2_INSTANCES + $instances)) + if ($v -eq $true){ + write-host "Region $r - EC2 instance count $instances" } - $instances=$(getInstances $r $profile) - $EC2_INSTANCES=$(($EC2_INSTANCES + $instances)) - $rds=$(getRDSInstances $r $profile) - $RDS_INSTANCES=$(($RDS_INSTANCES + $rds)) + $rds=$(getRDSInstances -region $r -profile $profile) + $global:RDS_INSTANCES=$(($global:RDS_INSTANCES + $rds)) + if ($v -eq $true){ + write-host "Region $r - RDS instance count $instances" + } - $redshift=$(getRedshift $r $profile) - $REDSHIFT_CLUSTERS=$(($REDSHIFT_CLUSTERS + $redshift)) + $redshift=$(getRedshift -region $r -profile $profile) + $global:REDSHIFT_CLUSTERS=$(($Rglobal:EDSHIFT_CLUSTERS + $redshift)) + if ($v -eq $true){ + write-host "Region $r - RedShift count $instances" + } - $elbv1=$(getElbv1 $r $profile) - $ELB_V1=$(($ELB_V1 + $elbv1)) + $elbv1=$(getElbv1 -region $r -profile $profile) + $global:ELB_V1=$(($global:ELB_V1 + $elbv1)) + if ($v -eq $true){ + write-host "Region $r - ELBv1 instance count $instances" + } - $elbv2=$(getElbv2 $r $profile) - $ELB_V2=$(($ELB_V2 + $elbv2)) + $elbv2=$(getElbv2 -region $r -profile $profile) + $global:ELB_V2=$(($global:ELB_V2 + $elbv2)) + if ($v -eq $true){ + write-host "Region $r - ELBv2 instance count $instances" + } - $natgw=$(getNatGateways $r $profile) - $NAT_GATEWAYS=$(($NAT_GATEWAYS + $natgw)) + $natgw=$(getNatGateways -region $r -profile $profile) + $global:NAT_GATEWAYS=$(($global:NAT_GATEWAYS + $natgw)) + if ($v -eq $true){ + write-host "Region $r - NAT_GW instance count $instances" + } } - - return $EC2_INSTANCES + $RDS_INSTANCES + $REDSHIFT_CLUSTERS + $ELB_V1 + $ELB_V2 + $NAT_GATEWAYS + + #return $global:EC2_INSTANCES + $global:RDS_INSTANCES + $global:REDSHIFT_CLUSTERS + $global:ELB_V1 + $global:ELB_V2 + $global:NAT_GATEWAYS } function textoutput { write-host "######################################################################" write-host "Lacework inventory collection complete." write-host "" - write-host "EC2 Instances: $EC2_INSTANCES" - write-host "RDS Instances: $RDS_INSTANCES" - write-host "Redshift Clusters: $REDSHIFT_CLUSTERS" - write-host "v1 Load Balancers: $ELB_V1" - write-host "v2 Load Balancers: $ELB_V2" - write-host "NAT Gateways: $NAT_GATEWAYS" + write-host "EC2 Instances: $global:EC2_INSTANCES" + write-host "RDS Instances: $global:RDS_INSTANCES" + write-host "Redshift Clusters: $global:REDSHIFT_CLUSTERS" + write-host "v1 Load Balancers: $global:ELB_V1" + write-host "v2 Load Balancers: $global:ELB_V2" + write-host "NAT Gateways: $global:NAT_GATEWAYS" write-host "====================" - write-host "Total Resources: $TOTAL" + write-host "Total Resources: $($global:EC2_INSTANCES + $global:RDS_INSTANCES + $global:REDSHIFT_CLUSTERS + $global:ELB_V1 + $global:ELB_V2 + $global:NAT_GATEWAYS)" } function jsonoutput { write-host "{" - write-host " \"ec2\": \"$EC2_INSTANCES\"," - write-host " \"rds\": \"$RDS_INSTANCES\"," - write-host " \"redshift\": \"$REDSHIFT_CLUSTERS\"," - write-host " \"v1_lb\": \"$ELB_V1\"," - write-host " \"v2_lb\": \"$ELB_V2\"," - write-host " \"nat_gw\": \"$NAT_GATEWAYS\"," - write-host " \"total\": \"$TOTAL\"" + write-host " \"ec2\": \"$global:EC2_INSTANCES\"," + write-host " \"rds\": \"$global:RDS_INSTANCES\"," + write-host " \"redshift\": \"$global:REDSHIFT_CLUSTERS\"," + write-host " \"v1_lb\": \"$global:ELB_V1\"," + write-host " \"v2_lb\": \"$global:ELB_V2\"," + write-host " \"nat_gw\": \"$global:NAT_GATEWAYS\"," + write-host " \"total\": \"$($global:EC2_INSTANCES + $global:RDS_INSTANCES + $global:REDSHIFT_CLUSTERS + $global:ELB_V1 + $global:ELB_V2 + $global:NAT_GATEWAYS)\"" write-host "}" } # TOOD: figure out if we support this? #foreach ($PROFILE in $(echo $AWS_PROFILE | sed "s/,/ /g")){ -$TOTAL = calculateInventory -profile $PROFILE +calculateInventory -profile $AWS_PROFILE #} if ($JSON -eq $true){ - write-host $jsonoutput + write-host jsonoutput }else{ - write-host $textoutput + write-host textoutput } diff --git a/test/todo.txt b/test/todo.txt new file mode 100644 index 0000000..e69de29 From 68fd7f37aaf89160eda8ddc4cd4f6db4958175ff Mon Sep 17 00:00:00 2001 From: Michael Droessler Date: Wed, 11 Aug 2021 16:52:18 -0500 Subject: [PATCH 03/13] wip 3 --- pwsh/lw_aws_inventory.ps1 | 45 +++++++++++++-------------------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/pwsh/lw_aws_inventory.ps1 b/pwsh/lw_aws_inventory.ps1 index 098e1cd..ac92500 100644 --- a/pwsh/lw_aws_inventory.ps1 +++ b/pwsh/lw_aws_inventory.ps1 @@ -22,28 +22,13 @@ param $AWS_PROFILE=$p -<# -# Usage: ./lw_aws_inventory.sh -while getopts ":jp:" opt; do - case ${opt} in - p ) - AWS_PROFILE=$OPTARG - ;; - j ) - JSON="true" - ;; - \? ) - echo "Usage: ./lw_aws_inventory.sh [-p profile] [-j]" 1>&2 - exit 1 - ;; - : ) - echo "Usage: ./lw_aws_inventory.sh [-p profile] [-j]" 1>&2 - exit 1 - ;; - esac -done -shift $((OPTIND -1)) -#> + +if (Get-Command "aws" -ErrorAction SilentlyContinue){ + $aws_installed = $true +}else{ + # setup aws-cli if not present? +} + # Set the initial counts to zero. $global:EC2_INSTANCES=0 @@ -137,31 +122,31 @@ function calculateInventory { $rds=$(getRDSInstances -region $r -profile $profile) $global:RDS_INSTANCES=$(($global:RDS_INSTANCES + $rds)) if ($v -eq $true){ - write-host "Region $r - RDS instance count $instances" + write-host "Region $r - RDS instance count $rds" } $redshift=$(getRedshift -region $r -profile $profile) $global:REDSHIFT_CLUSTERS=$(($Rglobal:EDSHIFT_CLUSTERS + $redshift)) if ($v -eq $true){ - write-host "Region $r - RedShift count $instances" + write-host "Region $r - RedShift count $redshift" } $elbv1=$(getElbv1 -region $r -profile $profile) $global:ELB_V1=$(($global:ELB_V1 + $elbv1)) if ($v -eq $true){ - write-host "Region $r - ELBv1 instance count $instances" + write-host "Region $r - ELBv1 instance count $elbv1" } $elbv2=$(getElbv2 -region $r -profile $profile) $global:ELB_V2=$(($global:ELB_V2 + $elbv2)) if ($v -eq $true){ - write-host "Region $r - ELBv2 instance count $instances" + write-host "Region $r - ELBv2 instance count $elbv2" } $natgw=$(getNatGateways -region $r -profile $profile) $global:NAT_GATEWAYS=$(($global:NAT_GATEWAYS + $natgw)) if ($v -eq $true){ - write-host "Region $r - NAT_GW instance count $instances" + write-host "Region $r - NAT_GW instance count $natgw" } } @@ -194,14 +179,14 @@ function jsonoutput { write-host "}" } -# TOOD: figure out if we support this? +# TOOD: figure out if we support this in windows? I have no idea what the format of multiple AWS_PROFILES is...looks like it could be a comma delimiter? #foreach ($PROFILE in $(echo $AWS_PROFILE | sed "s/,/ /g")){ calculateInventory -profile $AWS_PROFILE #} if ($JSON -eq $true){ - write-host jsonoutput + jsonoutput }else{ - write-host textoutput + textoutput } From f63f15fd2319a1da08e6a7cd7d288b51d152b618 Mon Sep 17 00:00:00 2001 From: Michael Droessler Date: Wed, 11 Aug 2021 17:01:06 -0500 Subject: [PATCH 04/13] wip 4 --- pwsh/lw_aws_inventory.ps1 | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/pwsh/lw_aws_inventory.ps1 b/pwsh/lw_aws_inventory.ps1 index ac92500..d37291f 100644 --- a/pwsh/lw_aws_inventory.ps1 +++ b/pwsh/lw_aws_inventory.ps1 @@ -10,7 +10,7 @@ param ( [CmdletBinding()] - [bool] $j = $false, + [bool] $json = $false, [CmdletBinding()] [string] $p = "default", @@ -27,6 +27,7 @@ if (Get-Command "aws" -ErrorAction SilentlyContinue){ $aws_installed = $true }else{ # setup aws-cli if not present? + throw "aws cli must be installed and configured prior to script execution!" } @@ -109,8 +110,8 @@ function calculateInventory { ) foreach ($r in $(getRegions -profile $profile)){ - if ($JSON -ne $true){ - #Write-Host $r + if ($json -ne $true){ + Write-Host $r } $instances=$(getInstances -region $r -profile $profile) @@ -169,13 +170,13 @@ function textoutput { function jsonoutput { write-host "{" - write-host " \"ec2\": \"$global:EC2_INSTANCES\"," - write-host " \"rds\": \"$global:RDS_INSTANCES\"," - write-host " \"redshift\": \"$global:REDSHIFT_CLUSTERS\"," - write-host " \"v1_lb\": \"$global:ELB_V1\"," - write-host " \"v2_lb\": \"$global:ELB_V2\"," - write-host " \"nat_gw\": \"$global:NAT_GATEWAYS\"," - write-host " \"total\": \"$($global:EC2_INSTANCES + $global:RDS_INSTANCES + $global:REDSHIFT_CLUSTERS + $global:ELB_V1 + $global:ELB_V2 + $global:NAT_GATEWAYS)\"" + write-host " `"ec2`": `"$global:EC2_INSTANCES`"," + write-host " `"rds`": `"$global:RDS_INSTANCES`"," + write-host " `"redshift`": `"$global:REDSHIFT_CLUSTERS`"," + write-host " `"v1_lb`": `"$global:ELB_V1`"," + write-host " `"v2_lb`": `"$global:ELB_V2`"," + write-host " `"nat_gw`": `"$global:NAT_GATEWAYS`"," + write-host " `"total`": `"$($global:EC2_INSTANCES + $global:RDS_INSTANCES + $global:REDSHIFT_CLUSTERS + $global:ELB_V1 + $global:ELB_V2 + $global:NAT_GATEWAYS)`"" write-host "}" } @@ -184,7 +185,7 @@ function jsonoutput { calculateInventory -profile $AWS_PROFILE #} -if ($JSON -eq $true){ +if ($json -eq $true){ jsonoutput }else{ textoutput From 9b3b619149bf9796ec39a7d3ce3458026faf4933 Mon Sep 17 00:00:00 2001 From: Michael Droessler Date: Wed, 11 Aug 2021 17:06:19 -0500 Subject: [PATCH 05/13] updated multiple profile support --- pwsh/lw_aws_inventory.ps1 | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/pwsh/lw_aws_inventory.ps1 b/pwsh/lw_aws_inventory.ps1 index d37291f..86d3b3e 100644 --- a/pwsh/lw_aws_inventory.ps1 +++ b/pwsh/lw_aws_inventory.ps1 @@ -1,7 +1,7 @@ # Script to fetch AWS inventory for Lacework sizing. # Requirements: awscli -# You can specify a profile with the -p flag, or get JSON output with the -j flag. +# You can specify a profile with the `-p $PROFILE_NAME` flag, or get JSON output with the `-json $true` flag. # Note: # 1. You can specify multiple accounts by passing a comma seperated list, e.g. "default,qa,test", # there are no spaces between accounts in the list @@ -20,9 +20,6 @@ param [bool] $v = $false ) -$AWS_PROFILE=$p - - if (Get-Command "aws" -ErrorAction SilentlyContinue){ $aws_installed = $true }else{ @@ -180,10 +177,9 @@ function jsonoutput { write-host "}" } -# TOOD: figure out if we support this in windows? I have no idea what the format of multiple AWS_PROFILES is...looks like it could be a comma delimiter? -#foreach ($PROFILE in $(echo $AWS_PROFILE | sed "s/,/ /g")){ -calculateInventory -profile $AWS_PROFILE -#} +foreach ($awsProfile in $($p.Split(",").Trim())){ + calculateInventory -profile $awsProfile +} if ($json -eq $true){ jsonoutput From 9d3154b210224a0f23415bcbb45539d2348b92e2 Mon Sep 17 00:00:00 2001 From: Michael Droessler Date: Wed, 11 Aug 2021 17:07:01 -0500 Subject: [PATCH 06/13] removed unused var --- pwsh/lw_aws_inventory.ps1 | 2 -- 1 file changed, 2 deletions(-) diff --git a/pwsh/lw_aws_inventory.ps1 b/pwsh/lw_aws_inventory.ps1 index 86d3b3e..2b770e0 100644 --- a/pwsh/lw_aws_inventory.ps1 +++ b/pwsh/lw_aws_inventory.ps1 @@ -36,8 +36,6 @@ $global:ELB_V1=0 $global:ELB_V2=0 $global:NAT_GATEWAYS=0 -$TOTAL = 0 - function getRegions { param( $profile From a6e07649a2b7323fec8995ef35f6d86ac166e481 Mon Sep 17 00:00:00 2001 From: Michael Droessler Date: Thu, 12 Aug 2021 07:44:15 -0500 Subject: [PATCH 07/13] rewrote azure script to ps1, resource graph for vnet gateways --- pwsh/lw_azure_inventory.ps1 | 54 +++++++++++++++++++++++++++++++++++++ pwsh/lw_gcp_inventory.ps1 | 0 2 files changed, 54 insertions(+) create mode 100644 pwsh/lw_azure_inventory.ps1 create mode 100644 pwsh/lw_gcp_inventory.ps1 diff --git a/pwsh/lw_azure_inventory.ps1 b/pwsh/lw_azure_inventory.ps1 new file mode 100644 index 0000000..aa4ab83 --- /dev/null +++ b/pwsh/lw_azure_inventory.ps1 @@ -0,0 +1,54 @@ +#!/bin/bash +# Script to fetch Azure inventory for Lacework sizing. +# Requirements: az cli + +# This script can be run from Azure Cloud Shell. + +# Set the initial counts to zero. +$AZURE_VMS=0 +$SQL_SERVERS=0 +$LOAD_BALANCERS=0 +$GATEWAYS=0 + +function getVMs { + $(az vm list -d --query "[?powerState=='VM running']" | ConvertFrom-Json).Count +} + +function getSQLServers { + $(az sql server list | ConvertFrom-Json).Count +} + +function getLoadBalancers { + $(az network lb list | ConvertFrom-Json).Count +} + +write-host "Starting inventory check." +write-host "Fetching VMs..." +$vms=$(getVMs) +$AZURE_VMS=$(($AZURE_VMS + $vms)) + +write-host "Fetching SQL Databases..." +$sql=$(getSQLServers) +$SQL_SERVERS=$(($SQL_SERVERS + $sql)) + +write-host "Fetching Load Balancers..." +$lbs=$(getLoadBalancers) +$LOAD_BALANCERS=$(($LOAD_BALANCERS + $lbs)) + +write-host "Fetching Gateways..." +#TODO -- replace this with a resource graph query... +# Microsoft.Network/virtualNetworkGateways +# need to run this to avoid an interactive prompt to use the resource graph extension +az config set extension.use_dynamic_install=yes_without_prompt +$GATEWAYS= $(az graph query -q "Resources | where type =~ 'Microsoft.Network/virtualNetworkGateways' | summarize count=count()" | ConvertFrom-Json).data.count + + +write-host "######################################################################" +write-host "Lacework inventory collection complete." +write-host "" +write-host "Azure VMs: $AZURE_VMS" +write-host "SQL Servers: $SQL_SERVERS" +write-host "Load Balancers: $LOAD_BALANCERS" +write-host "Vnet Gateways: $GATEWAYS" +write-host "====================" +write-host "Total Resources: $(($AZURE_VMS + $SQL_SERVERS + $LOAD_BALANCERS + $GATEWAYS))" diff --git a/pwsh/lw_gcp_inventory.ps1 b/pwsh/lw_gcp_inventory.ps1 new file mode 100644 index 0000000..e69de29 From 29f7b9a0f708a293fec425a8e1ee79f7d894a2e6 Mon Sep 17 00:00:00 2001 From: Michael Droessler Date: Thu, 12 Aug 2021 08:19:35 -0500 Subject: [PATCH 08/13] testing requried on azure, gcp wip --- pwsh/lw_azure_inventory.ps1 | 9 +++ pwsh/lw_gcp_inventory.ps1 | 113 ++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/pwsh/lw_azure_inventory.ps1 b/pwsh/lw_azure_inventory.ps1 index aa4ab83..9118cdf 100644 --- a/pwsh/lw_azure_inventory.ps1 +++ b/pwsh/lw_azure_inventory.ps1 @@ -3,6 +3,15 @@ # Requirements: az cli # This script can be run from Azure Cloud Shell. +param +( + [CmdletBinding()] + [bool] $json = $false, + + # enable verbose output + [CmdletBinding()] + [bool] $v = $false +) # Set the initial counts to zero. $AZURE_VMS=0 diff --git a/pwsh/lw_gcp_inventory.ps1 b/pwsh/lw_gcp_inventory.ps1 index e69de29..fc14705 100644 --- a/pwsh/lw_gcp_inventory.ps1 +++ b/pwsh/lw_gcp_inventory.ps1 @@ -0,0 +1,113 @@ +#!/bin/bash +# Script to fetch GCP inventory for Lacework sizing. +# Requirements: gcloud, jq +param +( + [CmdletBinding()] + [bool] $json = $false, + + # Uncomment and replace with your own list of projects. Otherwise the script + # scans all the projects in your organization. You must use the Project ID. + #project_ids=@("stitch-dev-289221","stitch-vault","stitch-jenkins-288315","stitch-infra") + [CmdletBinding()] + [array] $project_ids = $null, + + # enable verbose output + [CmdletBinding()] + [bool] $v = $false +) + +# Set the initial counts to zero. +$global:GCE_INSTANCES=0 +$global:GKE_INSTANCES=0 +$global:SQL_INSTANCES=0 +$global:LOAD_BALANCERS=0 +$global:GATEWAYS=0 + + + +function getProjects { + $(gcloud projects list --format json | ConvertFrom-Json).projectId +} + +function isComputeEnabled { + gcloud services list --format json | jq -r '.[] | .name' | grep -q "compute.googleapis.com" +} + +# NOTE - it is technically possible to have a CloudSQL instance without the +# sqladmin API enabled; but you cannot check the instance programatically +# without the API enabled +function isCloudSQLEnabled { + gcloud services list --format json | jq -r '.[] | .name' | grep -q "sqladmin.googleapis.com" +} + +function getGKEInstances { + gcloud compute instances list --format json | jq '[.[] | select(.name | contains("gke-"))] | length' +} + +function getGCEInstances { + gcloud compute instances list --format json | jq '[.[] | select(.name | contains("gke-") | not)] | length' +} + +function getSQLInstances { + $(gcloud sql instances list --format json | ConvertFrom-Json).Count +} + +function getLoadBalancers { + $(gcloud compute forwarding-rules list --format json | ConvertFrom-Json).Count +} + +function getGateways { + gcloud compute routers list --format json | jq '[.[] | .nats | length] | add' +} + +# Define PROJECT_IDS above to scan a subset of projects. Otherwise we scan +# all of the projects in the organization. +if ($project_ids -eq $null){ + $project_ids=$(getProjects) +} + +# Loop through all the projects and take inventory +foreach ($project in $project_ids){ + write-host "" + write-host "######################################################################" + write-host "Project: $project" + gcloud config set project $project + + if (isComputeEnabled) { + write-host "Checking for compute resources." + # Update the GCE instances + $gce_inst=$(getGCEInstances) + $global:GCE_INSTANCES=$(($global:GCE_INSTANCES + $gce_inst)) + + # Update the GKE instances + $gke_inst=$(getGKEInstances) + $global:GKE_INSTANCES=$(($global:GKE_INSTANCES + $gke_inst)) + + # Update the load balancers + $lbs=$(getLoadBalancers) + $global:LOAD_BALANCERS=$(($global:LOAD_BALANCERS + $lbs)) + + # Update the gateways + $gateways=$(getGateways) + $global:GATEWAYS=$(($global:GATEWAYS + $gateways)) + } + + # Check for SQL instances + if (isCloudSQLEnabled) { + write-host "Checking for Cloud SQL instances." + $sqls=$(getSQLInstances) + $global:SQL_INSTANCES=$(($global:SQL_INSTANCES + $sqls)) + } +} + +write-host "######################################################################" +write-host "Lacework inventory collection complete." +write-host "" +write-host "GCE Instances: $global:GCE_INSTANCES" +write-host "GKE Instances: $global:GKE_INSTANCES" +write-host "Load Balancers: $global:LOAD_BALANCERS" +write-host "Gateways: $global:GATEWAYS" +write-host "SQL Instances: $global:SQL_INSTANCES" +write-host "====================" +write-host "Total Resources: $(($global:GCE_INSTANCES + $global:GKE_INSTANCES + $global:LOAD_BALANCERS + $global:GATEWAYS + $global:SQL_INSTANCES))" From 1420dc1ee22b1ce622054e008f017946a1b8e58d Mon Sep 17 00:00:00 2001 From: Michael Droessler Date: Thu, 12 Aug 2021 08:28:39 -0500 Subject: [PATCH 09/13] gcp rewritten, untested --- pwsh/lw_gcp_inventory.ps1 | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/pwsh/lw_gcp_inventory.ps1 b/pwsh/lw_gcp_inventory.ps1 index fc14705..b64888e 100644 --- a/pwsh/lw_gcp_inventory.ps1 +++ b/pwsh/lw_gcp_inventory.ps1 @@ -24,29 +24,30 @@ $global:SQL_INSTANCES=0 $global:LOAD_BALANCERS=0 $global:GATEWAYS=0 - - function getProjects { $(gcloud projects list --format json | ConvertFrom-Json).projectId } function isComputeEnabled { - gcloud services list --format json | jq -r '.[] | .name' | grep -q "compute.googleapis.com" + #gcloud services list --format json | jq -r '.[] | .name' | grep -q "compute.googleapis.com" + $(gcloud services list --format json | ConvertFrom-Json).name -contains "compute.googleapis.com" } # NOTE - it is technically possible to have a CloudSQL instance without the # sqladmin API enabled; but you cannot check the instance programatically # without the API enabled function isCloudSQLEnabled { - gcloud services list --format json | jq -r '.[] | .name' | grep -q "sqladmin.googleapis.com" + $(gcloud services list --format json | ConvertFrom-Json).name -contains "sqladmin.googleapis.com" } function getGKEInstances { - gcloud compute instances list --format json | jq '[.[] | select(.name | contains("gke-"))] | length' + #gcloud compute instances list --format json | jq '[.[] | select(.name | contains("gke-"))] | length' + $((gcloud compute instances list --format json | ConvertFrom-Json).name | Where-Object {$_ -contains "gke-"}).Count } function getGCEInstances { - gcloud compute instances list --format json | jq '[.[] | select(.name | contains("gke-") | not)] | length' + #gcloud compute instances list --format json | jq '[.[] | select(.name | contains("gke-") | not)] | length' + $((gcloud compute instances list --format json | ConvertFrom-Json).name | Where-Object {$_ -notcontains "gke-"}).Count } function getSQLInstances { @@ -58,7 +59,8 @@ function getLoadBalancers { } function getGateways { - gcloud compute routers list --format json | jq '[.[] | .nats | length] | add' + #gcloud compute routers list --format json | jq '[.[] | .nats | length] | add' + $(gcloud compute routers list --format json | ConvertFrom-Json).nats.Count } # Define PROJECT_IDS above to scan a subset of projects. Otherwise we scan From 11c34c720651f0d6d8794a3e6cbd7cb3a50128a5 Mon Sep 17 00:00:00 2001 From: Michael Droessler Date: Sat, 14 Aug 2021 18:39:23 -0500 Subject: [PATCH 10/13] Update todo.txt --- test/todo.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/todo.txt b/test/todo.txt index e69de29..b72559d 100644 --- a/test/todo.txt +++ b/test/todo.txt @@ -0,0 +1,9 @@ +create resources of all types in AWS + - Terraform? +- run AWS bash script and assert correct count +- run AWS pwsh script and assert correct count + +rinse and repeat for Azure, GCP +ensure teardown of resources once complete + +no expectation of CI/CD at this time...just enough tools to validate code changes work as expected From d5ddffb886b0f91c75d6805d936981c7f63397ca Mon Sep 17 00:00:00 2001 From: Michael Droessler Date: Mon, 16 Aug 2021 16:52:32 -0500 Subject: [PATCH 11/13] updated output to stdout --- pwsh/lw_aws_inventory.ps1 | 40 ++++++++++++++++++------------------- pwsh/lw_azure_inventory.ps1 | 18 ++++++++--------- pwsh/lw_gcp_inventory.ps1 | 20 +++++++++---------- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/pwsh/lw_aws_inventory.ps1 b/pwsh/lw_aws_inventory.ps1 index 2b770e0..90aa815 100644 --- a/pwsh/lw_aws_inventory.ps1 +++ b/pwsh/lw_aws_inventory.ps1 @@ -150,29 +150,29 @@ function calculateInventory { } function textoutput { - write-host "######################################################################" - write-host "Lacework inventory collection complete." - write-host "" - write-host "EC2 Instances: $global:EC2_INSTANCES" - write-host "RDS Instances: $global:RDS_INSTANCES" - write-host "Redshift Clusters: $global:REDSHIFT_CLUSTERS" - write-host "v1 Load Balancers: $global:ELB_V1" - write-host "v2 Load Balancers: $global:ELB_V2" - write-host "NAT Gateways: $global:NAT_GATEWAYS" - write-host "====================" - write-host "Total Resources: $($global:EC2_INSTANCES + $global:RDS_INSTANCES + $global:REDSHIFT_CLUSTERS + $global:ELB_V1 + $global:ELB_V2 + $global:NAT_GATEWAYS)" + write-output "######################################################################" + write-output "Lacework inventory collection complete." + write-output "" + write-output "EC2 Instances: $global:EC2_INSTANCES" + write-output "RDS Instances: $global:RDS_INSTANCES" + write-output "Redshift Clusters: $global:REDSHIFT_CLUSTERS" + write-output "v1 Load Balancers: $global:ELB_V1" + write-output "v2 Load Balancers: $global:ELB_V2" + write-output "NAT Gateways: $global:NAT_GATEWAYS" + write-output "====================" + write-output "Total Resources: $($global:EC2_INSTANCES + $global:RDS_INSTANCES + $global:REDSHIFT_CLUSTERS + $global:ELB_V1 + $global:ELB_V2 + $global:NAT_GATEWAYS)" } function jsonoutput { - write-host "{" - write-host " `"ec2`": `"$global:EC2_INSTANCES`"," - write-host " `"rds`": `"$global:RDS_INSTANCES`"," - write-host " `"redshift`": `"$global:REDSHIFT_CLUSTERS`"," - write-host " `"v1_lb`": `"$global:ELB_V1`"," - write-host " `"v2_lb`": `"$global:ELB_V2`"," - write-host " `"nat_gw`": `"$global:NAT_GATEWAYS`"," - write-host " `"total`": `"$($global:EC2_INSTANCES + $global:RDS_INSTANCES + $global:REDSHIFT_CLUSTERS + $global:ELB_V1 + $global:ELB_V2 + $global:NAT_GATEWAYS)`"" - write-host "}" + write-output "{ " + write-output " `"ec2`": `"$global:EC2_INSTANCES`"," + write-output " `"rds`": `"$global:RDS_INSTANCES`"," + write-output " `"redshift`": `"$global:REDSHIFT_CLUSTERS`"," + write-output " `"v1_lb`": `"$global:ELB_V1`"," + write-output " `"v2_lb`": `"$global:ELB_V2`"," + write-output " `"nat_gw`": `"$global:NAT_GATEWAYS`"," + write-output " `"total`": `"$($global:EC2_INSTANCES + $global:RDS_INSTANCES + $global:REDSHIFT_CLUSTERS + $global:ELB_V1 + $global:ELB_V2 + $global:NAT_GATEWAYS)`"" + write-output "}" } foreach ($awsProfile in $($p.Split(",").Trim())){ diff --git a/pwsh/lw_azure_inventory.ps1 b/pwsh/lw_azure_inventory.ps1 index 9118cdf..4314c13 100644 --- a/pwsh/lw_azure_inventory.ps1 +++ b/pwsh/lw_azure_inventory.ps1 @@ -52,12 +52,12 @@ az config set extension.use_dynamic_install=yes_without_prompt $GATEWAYS= $(az graph query -q "Resources | where type =~ 'Microsoft.Network/virtualNetworkGateways' | summarize count=count()" | ConvertFrom-Json).data.count -write-host "######################################################################" -write-host "Lacework inventory collection complete." -write-host "" -write-host "Azure VMs: $AZURE_VMS" -write-host "SQL Servers: $SQL_SERVERS" -write-host "Load Balancers: $LOAD_BALANCERS" -write-host "Vnet Gateways: $GATEWAYS" -write-host "====================" -write-host "Total Resources: $(($AZURE_VMS + $SQL_SERVERS + $LOAD_BALANCERS + $GATEWAYS))" +write-output "######################################################################" +write-output "Lacework inventory collection complete." +write-output "" +write-output "Azure VMs: $AZURE_VMS" +write-output "SQL Servers: $SQL_SERVERS" +write-output "Load Balancers: $LOAD_BALANCERS" +write-output "Vnet Gateways: $GATEWAYS" +write-output "====================" +write-output "Total Resources: $(($AZURE_VMS + $SQL_SERVERS + $LOAD_BALANCERS + $GATEWAYS))" diff --git a/pwsh/lw_gcp_inventory.ps1 b/pwsh/lw_gcp_inventory.ps1 index b64888e..e321891 100644 --- a/pwsh/lw_gcp_inventory.ps1 +++ b/pwsh/lw_gcp_inventory.ps1 @@ -103,13 +103,13 @@ foreach ($project in $project_ids){ } } -write-host "######################################################################" -write-host "Lacework inventory collection complete." -write-host "" -write-host "GCE Instances: $global:GCE_INSTANCES" -write-host "GKE Instances: $global:GKE_INSTANCES" -write-host "Load Balancers: $global:LOAD_BALANCERS" -write-host "Gateways: $global:GATEWAYS" -write-host "SQL Instances: $global:SQL_INSTANCES" -write-host "====================" -write-host "Total Resources: $(($global:GCE_INSTANCES + $global:GKE_INSTANCES + $global:LOAD_BALANCERS + $global:GATEWAYS + $global:SQL_INSTANCES))" +write-output "######################################################################" +write-output "Lacework inventory collection complete." +write-output "" +write-output "GCE Instances: $global:GCE_INSTANCES" +write-output "GKE Instances: $global:GKE_INSTANCES" +write-output "Load Balancers: $global:LOAD_BALANCERS" +write-output "Gateways: $global:GATEWAYS" +write-output "SQL Instances: $global:SQL_INSTANCES" +write-output "====================" +write-output "Total Resources: $(($global:GCE_INSTANCES + $global:GKE_INSTANCES + $global:LOAD_BALANCERS + $global:GATEWAYS + $global:SQL_INSTANCES))" From 3af276ae3923a8ae7391b9af6e4b704c58539ea6 Mon Sep 17 00:00:00 2001 From: Michael Droessler Date: Tue, 17 Aug 2021 07:17:59 -0500 Subject: [PATCH 12/13] testing setup --- .gitignore | 2 + pwsh/lw_aws_inventory.ps1 | 2 +- test/aws/test.sh | 47 ++++++++ test/azure/main.tf | 225 ++++++++++++++++++++++++++++++++++++++ test/azure/test.sh | 15 +++ test/gcp/main.tf | 0 test/gcp/test.sh | 15 +++ 7 files changed, 305 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100755 test/aws/test.sh create mode 100644 test/azure/main.tf create mode 100644 test/azure/test.sh create mode 100644 test/gcp/main.tf create mode 100644 test/gcp/test.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..08b5469 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.terraform* +terraform* \ No newline at end of file diff --git a/pwsh/lw_aws_inventory.ps1 b/pwsh/lw_aws_inventory.ps1 index 90aa815..4405e9e 100644 --- a/pwsh/lw_aws_inventory.ps1 +++ b/pwsh/lw_aws_inventory.ps1 @@ -122,7 +122,7 @@ function calculateInventory { } $redshift=$(getRedshift -region $r -profile $profile) - $global:REDSHIFT_CLUSTERS=$(($Rglobal:EDSHIFT_CLUSTERS + $redshift)) + $global:REDSHIFT_CLUSTERS=$(($Rglobal:REDSHIFT_CLUSTERS + $redshift)) if ($v -eq $true){ write-host "Region $r - RedShift count $redshift" } diff --git a/test/aws/test.sh b/test/aws/test.sh new file mode 100755 index 0000000..98d3c58 --- /dev/null +++ b/test/aws/test.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +#setup RDS example +git clone https://github.com/terraform-aws-modules/terraform-aws-rds.git +cd ./terraform-aws-rds/examples/complete-mysql +terraform init +terraform apply --auto-approve +cd ../../.. + +# setup EC2 example +git clone https://github.com/terraform-aws-modules/terraform-aws-ec2-instance.git +cd ./terraform-aws-ec2-instance/examples/basic +terraform init +terraform apply --auto-approve +cd ../../.. + +#setup Redshift example +git clone https://github.com/terraform-aws-modules/terraform-aws-redshift.git +cd ./terraform-aws-redshift/examples/complete +terraform init +terraform apply --auto-approve +cd ../../.. + +#setup ELB example +git clone https://github.com/terraform-aws-modules/terraform-aws-elb.git +cd ./terraform-aws-elb/examples/complete +terraform init +terraform apply --auto-approve +cd ../../.. + +#setup NAT Gateway example -- TODO + +bash_results=$(sh ../../bash/lw_aws_inventory.sh -j) +echo $bash_results + +pwsh_results=$(pwsh -c "../../pwsh/lw_aws_inventory.ps1 -json 1") +echo $pwsh_results + +if [[ "$bash_results" == "$pwsh_results" ]]; then + echo "identical results!" + exit 0 +else + echo "results do not match" + exit 1 +fi + +#terraform destroy --auto-approve \ No newline at end of file diff --git a/test/azure/main.tf b/test/azure/main.tf new file mode 100644 index 0000000..415486c --- /dev/null +++ b/test/azure/main.tf @@ -0,0 +1,225 @@ + +provider "azurerm" { + features {} +} + +variable "prefix" { + default = "tfvmex" +} + +resource "azurerm_resource_group" "main" { + name = "${var.prefix}-resources" + location = "East US" +} + +resource "azurerm_virtual_network" "main" { + name = "${var.prefix}-network" + address_space = ["10.0.0.0/16"] + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name +} + +resource "azurerm_subnet" "internal" { + name = "internal" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name + address_prefixes = ["10.0.2.0/24"] +} + +resource "azurerm_network_interface" "main" { + name = "${var.prefix}-nic" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name + + ip_configuration { + name = "testconfiguration1" + subnet_id = azurerm_subnet.internal.id + private_ip_address_allocation = "Dynamic" + } +} + +resource "azurerm_virtual_machine" "main" { + name = "${var.prefix}-vm" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name + network_interface_ids = [azurerm_network_interface.main.id] + vm_size = "Standard_DS1_v2" + + # Uncomment this line to delete the OS disk automatically when deleting the VM + delete_os_disk_on_termination = true + + # Uncomment this line to delete the data disks automatically when deleting the VM + delete_data_disks_on_termination = true + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + storage_os_disk { + name = "myosdisk1" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Standard_LRS" + } + os_profile { + computer_name = "hostname" + admin_username = "testadmin" + admin_password = "Password1234!" + } + os_profile_linux_config { + disable_password_authentication = false + } + tags = { + environment = "staging" + } +} + +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West US" +} + +resource "azurerm_storage_account" "example" { + name = "examplesa" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_mssql_server" "example" { + name = "example-sqlserver" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + version = "12.0" + administrator_login = "4dm1n157r470r" + administrator_login_password = "4-v3ry-53cr37-p455w0rd" +} + +resource "azurerm_mssql_database" "test" { + name = "acctest-db-d" + server_id = azurerm_mssql_server.example.id + collation = "SQL_Latin1_General_CP1_CI_AS" + license_type = "LicenseIncluded" + max_size_gb = 4 + read_scale = true + sku_name = "BC_Gen5_2" + zone_redundant = true + + extended_auditing_policy { + storage_endpoint = azurerm_storage_account.example.primary_blob_endpoint + storage_account_access_key = azurerm_storage_account.example.primary_access_key + storage_account_access_key_is_secondary = true + retention_in_days = 6 + } + + + tags = { + foo = "bar" + } + +} + +resource "azurerm_resource_group" "example" { + name = "LoadBalancerRG" + location = "West US" +} + +resource "azurerm_public_ip" "example" { + name = "PublicIPForLB" + location = "West US" + resource_group_name = azurerm_resource_group.example.name + allocation_method = "Static" +} + +resource "azurerm_lb" "example" { + name = "TestLoadBalancer" + location = "West US" + resource_group_name = azurerm_resource_group.example.name + + frontend_ip_configuration { + name = "PublicIPAddress" + public_ip_address_id = azurerm_public_ip.example.id + } +} + +resource "azurerm_virtual_network" "example" { + name = "test" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + address_space = ["10.0.0.0/16"] +} + +resource "azurerm_subnet" "example" { + name = "GatewaySubnet" + resource_group_name = azurerm_resource_group.example.name + virtual_network_name = azurerm_virtual_network.example.name + address_prefixes = ["10.0.1.0/24"] +} + +resource "azurerm_public_ip" "example" { + name = "test" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + + allocation_method = "Dynamic" +} + +resource "azurerm_virtual_network_gateway" "example" { + name = "test" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + + type = "Vpn" + vpn_type = "RouteBased" + + active_active = false + enable_bgp = false + sku = "Basic" + + ip_configuration { + name = "vnetGatewayConfig" + public_ip_address_id = azurerm_public_ip.example.id + private_ip_address_allocation = "Dynamic" + subnet_id = azurerm_subnet.example.id + } + + vpn_client_configuration { + address_space = ["10.2.0.0/24"] + + root_certificate { + name = "DigiCert-Federated-ID-Root-CA" + + public_cert_data = < Date: Tue, 17 Aug 2021 15:37:12 -0500 Subject: [PATCH 13/13] wip --- pwsh/lw_aws_inventory.ps1 | 4 ++-- pwsh/lw_azure_inventory.ps1 | 36 +++++++++++++++++++++------- test/aws/test.sh | 18 +++++++++++--- test/azure/main.tf | 48 ++++++++++++++++++++----------------- test/azure/test.sh | 10 ++++---- 5 files changed, 75 insertions(+), 41 deletions(-) diff --git a/pwsh/lw_aws_inventory.ps1 b/pwsh/lw_aws_inventory.ps1 index 4405e9e..f797017 100644 --- a/pwsh/lw_aws_inventory.ps1 +++ b/pwsh/lw_aws_inventory.ps1 @@ -122,7 +122,7 @@ function calculateInventory { } $redshift=$(getRedshift -region $r -profile $profile) - $global:REDSHIFT_CLUSTERS=$(($Rglobal:REDSHIFT_CLUSTERS + $redshift)) + $global:REDSHIFT_CLUSTERS=$(($global:REDSHIFT_CLUSTERS + $redshift)) if ($v -eq $true){ write-host "Region $r - RedShift count $redshift" } @@ -164,7 +164,7 @@ function textoutput { } function jsonoutput { - write-output "{ " + write-output "{" write-output " `"ec2`": `"$global:EC2_INSTANCES`"," write-output " `"rds`": `"$global:RDS_INSTANCES`"," write-output " `"redshift`": `"$global:REDSHIFT_CLUSTERS`"," diff --git a/pwsh/lw_azure_inventory.ps1 b/pwsh/lw_azure_inventory.ps1 index 4314c13..4a87392 100644 --- a/pwsh/lw_azure_inventory.ps1 +++ b/pwsh/lw_azure_inventory.ps1 @@ -52,12 +52,30 @@ az config set extension.use_dynamic_install=yes_without_prompt $GATEWAYS= $(az graph query -q "Resources | where type =~ 'Microsoft.Network/virtualNetworkGateways' | summarize count=count()" | ConvertFrom-Json).data.count -write-output "######################################################################" -write-output "Lacework inventory collection complete." -write-output "" -write-output "Azure VMs: $AZURE_VMS" -write-output "SQL Servers: $SQL_SERVERS" -write-output "Load Balancers: $LOAD_BALANCERS" -write-output "Vnet Gateways: $GATEWAYS" -write-output "====================" -write-output "Total Resources: $(($AZURE_VMS + $SQL_SERVERS + $LOAD_BALANCERS + $GATEWAYS))" +function textoutput { + write-output "######################################################################" + write-output "Lacework inventory collection complete." + write-output "" + write-output "Azure VMs: $AZURE_VMS" + write-output "SQL Servers: $SQL_SERVERS" + write-output "Load Balancers: $LOAD_BALANCERS" + write-output "Vnet Gateways: $GATEWAYS" + write-output "====================" + write-output "Total Resources: $(($AZURE_VMS + $SQL_SERVERS + $LOAD_BALANCERS + $GATEWAYS))" +} + +function jsonoutput { + write-output "{" + write-output " `"vms`": `"$AZURE_VMS`"," + write-output " `"sqlservers`": `"$SQL_SERVERS`"," + write-output " `"lb`": `"$LOAD_BALANCERS`"," + write-output " `"vnetgw`": `"$GATEWAYS`"," + Write-output " `"total`": `"$($AZURE_VMS + $SQL_SERVERS + $LOAD_BALANCERS + $GATEWAYS)`"" + write-output "}" +} + +if ($json -eq $true){ + jsonoutput +}else{ + textoutput +} \ No newline at end of file diff --git a/test/aws/test.sh b/test/aws/test.sh index 98d3c58..ef97b77 100755 --- a/test/aws/test.sh +++ b/test/aws/test.sh @@ -37,11 +37,23 @@ pwsh_results=$(pwsh -c "../../pwsh/lw_aws_inventory.ps1 -json 1") echo $pwsh_results if [[ "$bash_results" == "$pwsh_results" ]]; then - echo "identical results!" + echo "identical results between bash and pwsh!" exit 0 else - echo "results do not match" + echo "results do not match!" exit 1 fi -#terraform destroy --auto-approve \ No newline at end of file +# cleanup +cd ./terraform-aws-rds/examples/complete-mysql +terraform destroy --auto-approve +cd ../../.. +cd ./terraform-aws-ec2-instance/examples/basic +terraform destroy --auto-approve +cd ../../.. +cd ./terraform-aws-redshift/examples/complete +terraform destroy --auto-approve +cd ../../.. +cd ./terraform-aws-elb/examples/complete +terraform destroy --auto-approve +cd ../../.. \ No newline at end of file diff --git a/test/azure/main.tf b/test/azure/main.tf index 415486c..042803b 100644 --- a/test/azure/main.tf +++ b/test/azure/main.tf @@ -81,8 +81,12 @@ resource "azurerm_resource_group" "example" { location = "West US" } +resource "random_id" "storageaccount" { + byte_length = 8 +} + resource "azurerm_storage_account" "example" { - name = "examplesa" + name = "${lower(random_id.storageaccount.hex)}" resource_group_name = azurerm_resource_group.example.name location = azurerm_resource_group.example.location account_tier = "Standard" @@ -106,7 +110,7 @@ resource "azurerm_mssql_database" "test" { max_size_gb = 4 read_scale = true sku_name = "BC_Gen5_2" - zone_redundant = true + zone_redundant = false extended_auditing_policy { storage_endpoint = azurerm_storage_account.example.primary_blob_endpoint @@ -122,55 +126,55 @@ resource "azurerm_mssql_database" "test" { } -resource "azurerm_resource_group" "example" { +resource "azurerm_resource_group" "example2" { name = "LoadBalancerRG" location = "West US" } -resource "azurerm_public_ip" "example" { +resource "azurerm_public_ip" "example2" { name = "PublicIPForLB" location = "West US" - resource_group_name = azurerm_resource_group.example.name + resource_group_name = azurerm_resource_group.example2.name allocation_method = "Static" } -resource "azurerm_lb" "example" { +resource "azurerm_lb" "example2" { name = "TestLoadBalancer" location = "West US" - resource_group_name = azurerm_resource_group.example.name + resource_group_name = azurerm_resource_group.example2.name frontend_ip_configuration { name = "PublicIPAddress" - public_ip_address_id = azurerm_public_ip.example.id + public_ip_address_id = azurerm_public_ip.example2.id } } -resource "azurerm_virtual_network" "example" { +resource "azurerm_virtual_network" "example2" { name = "test" - location = azurerm_resource_group.example.location - resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example2.location + resource_group_name = azurerm_resource_group.example2.name address_space = ["10.0.0.0/16"] } -resource "azurerm_subnet" "example" { +resource "azurerm_subnet" "example2" { name = "GatewaySubnet" - resource_group_name = azurerm_resource_group.example.name - virtual_network_name = azurerm_virtual_network.example.name + resource_group_name = azurerm_resource_group.example2.name + virtual_network_name = azurerm_virtual_network.example2.name address_prefixes = ["10.0.1.0/24"] } -resource "azurerm_public_ip" "example" { +resource "azurerm_public_ip" "example3" { name = "test" - location = azurerm_resource_group.example.location - resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example2.location + resource_group_name = azurerm_resource_group.example2.name allocation_method = "Dynamic" } -resource "azurerm_virtual_network_gateway" "example" { +resource "azurerm_virtual_network_gateway" "example2" { name = "test" - location = azurerm_resource_group.example.location - resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example2.location + resource_group_name = azurerm_resource_group.example2.name type = "Vpn" vpn_type = "RouteBased" @@ -181,9 +185,9 @@ resource "azurerm_virtual_network_gateway" "example" { ip_configuration { name = "vnetGatewayConfig" - public_ip_address_id = azurerm_public_ip.example.id + public_ip_address_id = azurerm_public_ip.example3.id private_ip_address_allocation = "Dynamic" - subnet_id = azurerm_subnet.example.id + subnet_id = azurerm_subnet.example2.id } vpn_client_configuration { diff --git a/test/azure/test.sh b/test/azure/test.sh index fb99cd3..7ac46b9 100644 --- a/test/azure/test.sh +++ b/test/azure/test.sh @@ -1,14 +1,14 @@ terraform init terraform apply --auto-approve -bash_results=$(sh ../../bash/lw_azure_inventory.sh -j) -pwsh_results=$(pwsh -c "../../pwsh/lw_azure_inventory.ps1 -json 1") +bash_results=$(sh ../../bash/lw_azure_inventory.sh) #bash doesn't have json support..yet +pwsh_results=$(pwsh -c "../../pwsh/lw_azure_inventory.ps1") -if [ $bash_results == $pwsh_results ]; then - echo "identical results!" +if [[ "$bash_results" == "$pwsh_results" ]]; then + echo "identical results between bash and pwsh!" exit 0 else - echo "results do not match" + echo "results do not match!" exit 1 fi