forked from aws-samples/ec2-classic-resource-finder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathClassic-Resource-Finder.sh
executable file
·344 lines (316 loc) · 29.4 KB
/
Classic-Resource-Finder.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
#!/bin/bash
#
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
# software and associated documentation files (the "Software"), to deal in the Software
# without restriction, including without limitation the rights to use, copy, modify,
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
profile=${AWS_PROFILE:-default}
header=${OUTPUT_HEADER:-1}
## Unset a bunch of variables we will use later
unset awscurrentversion awsversionregex jqtest cuttest region classicstatus ec2next ec2loopcounter ec2raw sgnext sgloopcounter sgraw asgnext asgloopcounter \
asgraw clbnext clbloopcounter clbraw rdsnext rdsloopcounter rdsraw ecachenext ecacheloopcounter ecacheraw redshiftnext redshiftloopcounter redshiftraw ebappnext \
ebapploopcounter ebappraw ebenvapp ebapp ebenv ebnsval ebnsvalregex dpnext dploopcounter dpraw pipeline dpdefinition dpdefinitionregex emrnext emrloopcounter \
emrraw emrclust emrclustconfig emrsubnetid emrrequestedsubnetids
## Check to make sure AWS CLI is installed
awscurrentversion=`aws --version 2>&1` ## Get the version of the AWS CLI installed. If the AWS CLI is not installed the error pipes to dev null
awsversionregex="^(aws-cli\/)" ## Set the regex we compare the AWS CLI version against to make sure a valid version of AWS CLI is installed
if [[ ! $awscurrentversion =~ $awsversionregex ]] ## If the AWS CLI version does not fit to the regex for a valid AWS CLI version
then printf "AWS CLI does not appear to be installed, please install the AWS CLI and try running this again.\n" ## Then print an error
exit 1 ## and exit the script with a non success (non-zero) error code
fi
jqtest=`jq -r '.test' <<< '{"test": "success"}' 2>> errors.txt` ## Parse a simple JSON input to output "success", pipe all errors to dev null
if [[ ! $jqtest == "success" ]] ## If the test did not result in the output of "success"
then printf "JQ does not appear to be installed, please install JQ and try running this again.\n" ## Then print an error
exit 1 ## and exit the script with a non success (non-zero) error code
fi
cuttest=`cut -d " " -f2 <<< "fail success" 2>> errors.txt` ## Parse a simple input to output "success", pipe all errors to dev null
if [[ ! $cuttest == "success" ]] ## If the test did not result in the output of "success"
then printf "cut does not appear to be installed, please install cut and try this again.\n" ## Then print an error
exit 1 ## and exit the script with a non success (non-zero) error code
fi
## Search for EC2-Classic Resources
declare -a regions=('us-east-1' 'eu-west-1' 'us-west-1' 'ap-southeast-1' 'ap-northeast-1' 'us-west-2' 'sa-east-1' 'ap-southeast-2') ## Define regions that support EC2-Classic
i=0
for region in "${regions[@]}" ## Loop through the regions that support EC2-Classic
do
printf "# -------------------------------------------------------------------------\nSearching for resources in EC2-Classic in $region\n# -------------------------------------------------------------------------\n\n"
## Get Enablement Status
printf "Determining if EC2-Classic is enabled..."
[[ $header == 0 ]] || echo "profile,region,status" >> Classic_Platform_Status.csv
classicstatus=`aws ec2 describe-account-attributes --attribute-names supported-platforms --region $region --output json 2>> errors.txt` ## Get supported platforms for the region.
if [[ ${#classicstatus} -gt 2 ]] ## Make sure we got a return value
then classicstatusfiltered=`jq -r '.AccountAttributes[] .AttributeValues[] | select(.AttributeValue=="EC2") | .AttributeValue' <<< $classicstatus 2>> errors.txt` ##Filter the input to determine if EC2 (classic) is supported
if [[ ${#classicstatusfiltered} -gt 2 ]]
then printf "$profile,$region,Enabled\n" >> Classic_Platform_Status.csv ## If supported platforms includes EC2 in addition to VPC, output the region and Enabled to a CSV
else printf "$profile,$region,Disabled\n" >> Classic_Platform_Status.csv ## If supported platforms is only VPC and does not include EC2, output the region and Disabled to a CSV
fi
else printf "$region, Unknown\n" >> Classic_Platform_Status.csv
fi
printf "Done \xe2\x9c\x85 \n"
## Search for EIPs
printf "Searching for EIPs in EC2-Classic..."
[[ $header == 0 ]] || echo "profile,region,PublicIp,InstanceId" >> Classic_EIPs.csv
aws ec2 describe-addresses \
--filters Name=domain,Values=standard \
--region $region \
--output json 2>> errors.txt \
| jq -r --arg profile "$profile" --arg region "$region" \
'.Addresses[] | [$profile, $region, .PublicIp, .InstanceId] | @csv' >> Classic_EIPs.csv ## Get all EIPs in EC2-Classic and output them with their corresponding region to a CSV
printf "Done \xe2\x9c\x85 \n"
## Search for EC2 Instances
printf "Searching for any EC2-Classic instances..."
[[ $header == 0 ]] || echo "profile,region,Name,InstanceId,InstanceType" >> Classic_EC2_Instances.csv
ec2next="placeholder" ## Set a placeholder value for pagination token so the while loop kicks in. It gets dropped later in an IF statement.
declare -i ec2loopcounter ## Set a variable as int for loop counter
ec2loopcounter=1 ## Set the loop counter value to 1
while [[ ${#ec2next} -gt 10 ]] && [[ $ec2loopcounter -lt 100 ]] ## While the next token is not empty or "null" and the loopcounter is less than 100
do
if [[ $ec2next == "placeholder" ]] ## If token is still the placeholder, dont pass a starting-token else pass the starting token
then ec2raw=`aws ec2 describe-instances --region $region --filter Name=instance-state-name,Values=pending,running,shutting-down,stopping,stopped --query '{NextToken:NextToken,Reservations:Reservations[*].Instances[?VpcId==\`null\`]}' --output json 2>> errors.txt` ## Get the NextToken and InstanceID in JSON and store it in a variable
else ec2raw=`aws ec2 describe-instances --region $region --filter Name=instance-state-name,Values=pending,running,shutting-down,stopping,stopped --query '{NextToken:NextToken,Reservations:Reservations[*].Instances[?VpcId==\`null\`]}' --starting-token $ec2next --output json 2>> errors.txt` ## Get the NextToken and InstanceID in in JSON starting at the current token value and store it in a variable
fi
ec2next=`jq -r '.NextToken' <<< $ec2raw 2>> errors.txt` ## Use JQ to parse the NextToken and store it in a variable
jq -r --arg profile "$profile" --arg region "$region" '.Reservations[] | .[] | [$profile, $region, (.Tags[] | select(.[] == "Name").Value), .InstanceId, .InstanceType] | @csv' <<< $ec2raw >> Classic_EC2_Instances.csv ## Parse the instance IDs, append the region to each line delimited by a comma and output to the CSV
ec2loopcounter=$((ec2loopcounter + 1))
done
printf "Done \xe2\x9c\x85 \n"
## Search for Security Groups
printf "Searching for any Security Groups not in a VPC..."
[[ $header == 0 ]] || echo "profile,region,GroupName,GroupId" >> Classic_SGs.csv
sgnext="placeholder" ## Set a placeholder value for pagination token so the while loop kicks in. It gets dropped later in an IF statement.
declare -i sgloopcounter ## Set a variable as int for loop counter
sgloopcounter=1 ## Set the loop counter value to 1
while [[ ${#sgnext} -gt 10 ]] && [[ $sgloopcounter -lt 100 ]] ## While the next token is not empty or "null" and the loopcounter is less than 100
do
if [[ $sgnext == "placeholder" ]] ## If token is still the placeholder, dont pass a starting-token else pass the starting token
then sgraw=`aws ec2 describe-security-groups --query '{NextToken:NextToken,SecurityGroups:SecurityGroups[?VpcId==\`null\`]}' --region $region --output json 2>> errors.txt` ## Get the NextToken and Security GroupID in JSON and store it in a variable
else sgraw=`aws ec2 describe-security-groups --query '{NextToken:NextToken,SecurityGroups:SecurityGroups[?VpcId==\`null\`]}' --region $region --output json --starting-token $sgnext 2>> errors.txt` ## Get the NextToken and Security GroupID in in JSON starting at the current token value and store it in a variable
fi
sgnext=`jq -r '.NextToken' <<< $sgraw 2>> errors.txt` ## Use JQ to parse the NextToken and store it in a variable
jq -r --arg profile "$profile" --arg region "$region" '.SecurityGroups[] | [$profile, $region, .GroupName, .GroupId] | @csv' <<< $sgraw >> Classic_SGs.csv ## Parse the Security Group IDs, append the region to each line delimited by a comma and output to the CSV
sgloopcounter=$((sgloopcounter + 1))
done
printf "Done \xe2\x9c\x85 \n"
## Search VPC Classic Links
printf "Searching for VPCs with ClassicLink Enabled..."
[[ $header == 0 ]] || echo "profile,region,VpcId" >> Classic_ClassicLink_VPCs.csv
aws ec2 describe-vpc-classic-link --filter "Name=is-classic-link-enabled,Values=true" --region $region --output json 2>> errors.txt \
| jq -r --arg profile "$profile" --arg region "$region" '.Vpcs[] | [$profile, $region, .VpcId] | @csv' >> Classic_ClassicLink_VPCs.csv ## Get all VPC IDs with ClassicLink emabled and output them with their corresponding region to a CSV
printf "Done \xe2\x9c\x85 \n"
## Search for Auto-Scaling Groups
printf "Searching for Auto-Scaling groups without a VPC configured..."
[[ $header == 0 ]] || echo "profile,region,AutoScalingGroupARN" >> Classic_Auto_Scaling_Groups.csv
asgnext="placeholder" ## Set a placeholder value for pagination token so the while loop kicks in. It gets dropped later in an IF statement.
declare -i asgloopcounter ## Set a variable as int for loop counter
asgloopcounter=1 ## Set the loop counter value to 1
while [[ ${#asgnext} -gt 10 ]] && [[ $asgloopcounter -lt 100 ]] ## While the next token is not empty or "null" and the loopcounter is less than 100
do
if [[ $asgnext == "placeholder" ]] ## If token is still the placeholder, dont pass a starting-token else pass the starting token
then asgraw=`aws autoscaling describe-auto-scaling-groups --query '{NextToken:NextToken,AutoScalingGroups:AutoScalingGroups[?VPCZoneIdentifier==\`\`]}' --region $region --output json 2>> errors.txt` ## Get the NextToken and ASG ARN in JSON and store it in a variable
else asgraw=`aws autoscaling describe-auto-scaling-groups --query '{NextToken:NextToken,AutoScalingGroups:AutoScalingGroups[?VPCZoneIdentifier==\`\`]}' --region $region --output json --starting-token $asgnext 2>> errors.txt` ## Get the NextToken and ASG ARN in in JSON starting at the current token value and store it in a variable
fi
asgnext=`jq -r '.NextToken' <<< $asgraw 2>> errors.txt` ## Use JQ to parse the NextToken and store it in a variable
jq -r --arg profile "$profile" --arg region "$region" '.AutoScalingGroups[] | [$profile, $region, .AutoScalingGroupARN] | @csv' <<< $asgraw >> Classic_Auto_Scaling_Groups.csv ## Parse the ASG ARN, append the region to each line delimited by a comma and output to the CSV
asgloopcounter=$((asgloopcounter + 1))
done
printf "Done \xe2\x9c\x85 \n"
## Search for CLBs
printf "Searching for any Classic Load Balancer in EC2-Classic..."
[[ $header == 0 ]] || echo "profile,region,LoadBalancerName" >> Classic_CLBs.csv
clbnext="placeholder" ## Set a placeholder value for pagination token so the while loop kicks in. It gets dropped later in an IF statement.
declare -i clbloopcounter ## Set a variable as int for loop counter
clbloopcounter=1 ## Set the loop counter value to 1
while [[ ${#clbnext} -gt 10 ]] && [[ $clbloopcounter -lt 100 ]] ## While the next token is not empty or "null" and the loopcounter is less than 100
do
if [[ $clbnext == "placeholder" ]] ## If token is still the placeholder, dont pass a starting-token else pass the starting token
then clbraw=`aws elb describe-load-balancers --query '{NextMarker:NextMarker,LoadBalancerName:LoadBalancerDescriptions[?VPCId==\`null\`]}' --region $region --output json 2>> errors.txt` ## Get the NextMarker and CLB Name in JSON and store it in a variable
else clbraw=`aws elb describe-load-balancers --query '{NextMarker:NextMarker,LoadBalancerName:LoadBalancerDescriptions[?VPCId==\`null\`]}' --region $region --starting-token $clbnext --output json 2>> errors.txt` ## Get the NextMarker and CLB Name in in JSON starting at the current token value and store it in a variable
fi
clbnext=`jq -r '.NextMarker' <<< $clbraw 2>> errors.txt` ## Use JQ to parse the NextMarker and store it in a variable
jq -r --arg profile "$profile" --arg region "$region" '.LoadBalancerName[] | [$profile, $region, .LoadBalancerName] | @csv' <<< $clbraw 2>> errors.txt >> Classic_CLBs.csv ## Parse the CLB Name, append the region to each line delimited by a comma and output to the CSV
clbloopcounter=$((clbloopcounter + 1))
done
printf "Done \xe2\x9c\x85 \n"
## Search for RDS DBs
printf "Searching for any RDS-Classic instances..."
[[ $header == 0 ]] || echo "profile,region,DBInstanceArn" >> Classic_RDS_Instances.csv
rdsnext="placeholder" ## Set a placeholder value for pagination token so the while loop kicks in. It gets dropped later in an IF statement.
declare -i rdsloopcounter ## Set a variable as int for loop counter
rdsloopcounter=1 ## Set the loop counter value to 1
while [[ ${#rdsnext} -gt 10 ]] && [[ $rdsloopcounter -lt 100 ]] ## While the next token is not empty or "null" and the loopcounter is less than 100
do
if [[ $rdsnext == "placeholder" ]] ## If token is still the placeholder, dont pass a starting-token else pass the starting token
then rdsraw=`aws rds describe-db-instances --query '{NextToken:NextToken,DBInstanceArn:DBInstances[*].DBInstanceArn}' --region $region --output json 2>> errors.txt` ## Get the NextToken and DB ARN in JSON and store it in a variable
else rdsraw=`aws rds describe-db-instances --query '{NextToken:NextToken,DBInstanceArn:DBInstances[*].DBInstanceArn}' --region $region --starting-token $rdsnext --output json 2>> errors.txt` ## Get the NextToken and DB ARN in in JSON starting at the current token value and store it in a variable
fi
rdsnext=`jq -r '.NextToken' <<< $rdsraw 2>> errors.txt` ## Use JQ to parse the NextToken and store it in a variable
for dbinstance in `jq -r '.DBInstanceArn[]' <<< $rdsraw 2>> errors.txt` ## Loop through all DB Instances
do
instancesg=`aws rds describe-db-instances --filters Name=db-instance-id,Values=$dbinstance --query 'DBInstances[*].VpcSecurityGroups[*].VpcSecurityGroupId' --region $region --output text 2>> errors.txt` ## Get the VPC Security Group ID[s] attached. If it is classic, this will be empty.
if [[ ${#instancesg} -lt 5 ]] ## If the return is empty, thus classic then:
then printf "$profile,$region,$dbinstance \n" >> Classic_RDS_Instances.csv ## Print the DB Instance ARN and Region and output it to a CSV
fi
unset instancesg ## Clean up our variable from this loop
done
rdsloopcounter=$((rdsloopcounter + 1))
unset dbinstance rdsraw ## Clean up our variables from this loop
done
printf "Done \xe2\x9c\x85 \n"
## Search for ElastiCache Clusters
printf "Searching for any Elasticache clusters not in a VPC..."
[[ $header == 0 ]] || echo "profile,region,ARN" >> Classic_ElastiCache_Clusters.csv
ecachenext="placeholder" ## Set a placeholder value for pagination token so the while loop kicks in. It gets dropped later in an IF statement.
declare -i ecacheloopcounter ## Set a variable as int for loop counter
ecacheloopcounter=1 ## Set the loop counter value to 1
while [[ ${#ecachenext} -gt 10 ]] && [[ $ecacheloopcounter -lt 100 ]] ## While the next token is not empty or "null" and the loopcounter is less than 100
do
if [[ $ecachenext == "placeholder" ]] ## If token is still the placeholder, dont pass a starting-token else pass the starting token
then ecacheraw=`aws elasticache describe-cache-clusters --query '{NextToken:NextToken,ARN:CacheClusters[?CacheSubnetGroupName==\`null\`]}' --region $region --output json 2>> errors.txt` ## Get the NextToken and Cluster ARN in JSON and store it in a variable
else ecacheraw=`aws elasticache describe-cache-clusters --query '{NextToken:NextToken,ARN:CacheClusters[?CacheSubnetGroupName==\`null\`]}' --region $region --starting-token $ecachenext --output json 2>> errors.txt` ## Get the NextToken and Cluster ARN in in JSON starting at the current token value and store it in a variable
fi
ecachenext=`jq -r '.NextToken' <<< $ecacheraw 2>> errors.txt` ## Use JQ to parse the NextToken and store it in a variable
jq -r --arg profile "$profile" --arg region "$region" '.ARN[] | [$profile, $region, .ARN] | @csv' <<< $ecacheraw 2>> errors.txt >> Classic_ElastiCache_Clusters.csv ## Parse the Cluster ARN, append the region to each line delimited by a comma and output to the CSV
ecacheloopcounter=$((ecacheloopcounter + 1))
done
printf "Done \xe2\x9c\x85 \n"
## Search for Redshift Cluster
printf "Searching for any Redshift clusters not in a VPC..."
[[ $header == 0 ]] || echo "profile,region,ClusterIdentifier" >> Classic_Redshift_Clusters.csv
redshiftnext="placeholder" ## Set a placeholder value for pagination token so the while loop kicks in. It gets dropped later in an IF statement.
declare -i redshiftloopcounter ## Set a variable as int for loop counter
redshiftloopcounter=1 ## Set the loop counter value to 1
while [[ ${#redshiftnext} -gt 10 ]] && [[ $redshiftloopcounter -lt 100 ]] ## While the next token is not empty or "null" and the loopcounter is less than 100
do
if [[ $redshiftnext == "placeholder" ]] ## If token is still the placeholder, dont pass a starting-token else pass the starting token
then redshiftraw=`aws redshift describe-clusters --query '{NextToken:NextToken,ClusterIdentifier:Clusters[?VpcId==\`null\`]}' --region $region --output json 2>> errors.txt` ## Get the NextToken and Cluster Identifier in JSON and store it in a variable
else redshiftraw=`aws redshift describe-clusters --query '{NextToken:NextToken,ClusterIdentifier:Clusters[?VpcId==\`null\`]}' --region $region --starting-token $redshiftnext --output json 2>> errors.txt` ## Get the NextToken and Cluster Identifier in in JSON starting at the current token value and store it in a variable
fi
redshiftnext=`jq -r '.NextToken' <<< $redshiftraw 2>> errors.txt` ## Use JQ to parse the NextToken and store it in a variable
jq -r --arg profile "$profile" --arg region "$region" '.ClusterIdentifier[] | [$profile, $region, .ClusterIdentifier] | @csv' <<< $redshiftraw 2>> errors.txt >> Classic_Redshift_Clusters.csv ## Parse the Cluster Identifier, append the region to each line delimited by a comma and output to the CSV
redshiftloopcounter=$((redshiftloopcounter + 1))
done
printf "Done \xe2\x9c\x85 \n"
## Search for ElasticBeanstalk Environments
printf "Searching for any ElasticBeanstalk Environments without a VPC..."
[[ $header == 0 ]] || echo "profile,region,application-name,environment-name" >> Classic_ElasticBeanstalk_Applications_Environments.csv
ebappnext="placeholder" ## Set a placeholder value for pagination token so the while loop kicks in. It gets dropped later in an IF statement.
declare -i ebapploopcounter ## Set a variable as int for loop counter
ebapploopcounter=1 ## Set the loop counter value to 1
while [[ ${#ebappnext} -gt 10 ]] && [[ $ebapploopcounter -lt 100 ]] ## While the next token is not empty or "null" and the loopcounter is less than 100
do
if [[ $ebappnext == "placeholder" ]] ## If token is still the placeholder, dont pass a starting-token else pass the starting token
then ebappraw=`aws elasticbeanstalk describe-environments --no-include-deleted --query '{NextToken:NextToken,Environments:Environments[*]}' --region $region --output json 2>> errors.txt` ## Get the NextToken and environment values in JSON and store it in a variable
else ebappraw=`aws elasticbeanstalk describe-environments --no-include-deleted --query 'Environments[*]' --region $region --output json --starting-token $ebappnext 2>> errors.txt` ## Get the NextToken and environment values in in JSON starting at the current token value and store it in a variable
fi
ebappnext=`jq -r '.NextToken' <<< $ebappraw 2>> errors.txt` ## Use JQ to parse the NextToken and store it in a variable
IFS=$'\n' ## Set our internal field seperator to newline so we ignore the space delimiter in the for loop
for ebenvapp in `jq -r '.Environments[] | .ApplicationName +" "+ .EnvironmentName' <<< $ebappraw 2>> errors.txt` ## Loop over each application and environment pair
do
ebapp=`cut -d " " -f1 <<< $ebenvapp 2>> errors.txt` ## Extract the Application name
ebenv=`cut -d " " -f2 <<< $ebenvapp 2>> errors.txt` ## Extract the Environment name
ebnsval=`aws elasticbeanstalk describe-configuration-settings --application-name $ebapp --environment-name $ebenv --query 'ConfigurationSettings[*].OptionSettings[?Namespace==\`aws:ec2:vpc\`&&OptionName==\`VPCId\`&&Value!=\`null\`].OptionName' --region $region --output text 2>> errors.txt` ## If the environment is configured for a vpc return "VPCId"
ebnsvalregex="VPCId"
if [[ ! $ebnsval == $ebnsvalregex ]] ## If the configuration does not have a VPC:
then printf "$profile,$region,$ebapp,$ebenv\n" >> Classic_ElasticBeanstalk_Applications_Environments.csv ## Return the Application Name, Environment Name and Region for EB that doesnt have a VPC
fi
unset ebapp
unset ebenv
unset ebnsval
unset ebnsvalregex
done
unset ebappraw
unset ebenvapp
done
printf "Done \xe2\x9c\x85 \n"
## Search for DataPipelines
printf "Searching for any DataPipelines that dont have subnets associated..."
[[ $header == 0 ]] || echo "profile,region,pipeline-id" >> Classic_DataPipelines.csv
dpnext="placeholder" ## Set a placeholder value for pagination token so the while loop kicks in. It gets dropped later in an IF statement.
declare -i dploopcounter ## Set a variable as int for loop counter
dploopcounter=1 ## Set the loop counter value to 1
while [[ ${#dpnext} -gt 10 ]] && [[ $dploopcounter -lt 100 ]] ## While the next token is not empty or "null" and the loopcounter is less than 100
do
if [[ $dpnext == "placeholder" ]] ## If token is still the placeholder, dont pass a starting-token else pass the starting token
then dpraw=`aws datapipeline list-pipelines --query '{NextToken:NextToken,id:pipelineIdList[*]}' --region $region --output json 2>> errors.txt` ## Get the NextToken and Pipeline ID in JSON and store it in a variable
else dpraw=`aws datapipeline list-pipelines --query '{NextToken:NextToken,id:pipelineIdList[*]}' --region $region --starting-token $dpnext --output json 2>> errors.txt` ## Get the NextToken and Pipeline ID in in JSON starting at the current token value and store it in a variable
fi
dpnext=`jq -r '.NextToken' <<< $dpraw 2>> errors.txt` ## Use JQ to parse the NextToken and store it in a variable
for pipeline in `jq -r '.id[] .id' <<< $dpraw 2>> errors.txt` ## Parse the Cluster Identifier, append the region to each line delimited by a comma and output to the CSV
do
dpdefinition=`aws datapipeline get-pipeline-definition --pipeline-id $pipeline --query 'objects[?type==\`Ec2Resource\`&&subnetId==\`null\`].type' --region $region --output text 2>> errors.txt` ## Return "Ec2Resource" only if the ec2 resource subnet ID is null
dpdefinitionregex="Ec2Resource"
if [[ $dpdefinition == $dpdefinitionregex ]]
then printf "$profile,$region,$pipeline\n" >> Classic_DataPipelines.csv ## Return the Pipeline ID and region and output it to a CSV
fi
unset dpdefinition
unset dpdefinitionregex
done
unset pipeline
unset dpraw
dploopcounter=$((dploopcounter + 1))
done
printf "Done \xe2\x9c\x85 \n"
## Search for EMR Clusters
printf "Searching for EMR clusters not configured to launch in a subnet..."
[[ $header == 0 ]] || echo "profile,region,cluster-id" >> Classic_EMR_Clusters.csv
emrnext="placeholder" ## Set a placeholder value for pagination token so the while loop kicks in. It gets dropped later in an IF statement.
declare -i emrloopcounter ## Set a variable as int for loop counter
emrloopcounter=1 ## Set the loop counter value to 1
while [[ ${#emrnext} -gt 10 ]] && [[ $emrloopcounter -lt 100 ]] ## While the next token is not empty or "null" and the loopcounter is less than 100
do
if [[ $emrnext == "placeholder" ]] ## If token is still the placeholder, dont pass a starting-token else pass the starting token
then emrraw=`aws emr list-clusters --active --query '{NextToken:NextToken,id:Clusters[*]}' --region $region --output json 2>> errors.txt` ## Get the NextToken and cluster ID in JSON and store it in a variable
else emrraw=`aws emr list-clusters --active --query '{NextToken:NextToken,id:Clusters[*]}' --region $region --starting-token $emrnext --output json 2>> errors.txt` ## Get the NextToken and cluster ID in in JSON starting at the current token value and store it in a variable
fi
emrnext=`jq -r '.NextToken' <<< $emrraw 2>> errors.txt` ## Use JQ to parse the NextToken and store it in a variable
for emrclust in `jq -r '.id[] .Id' <<< $emrraw 2>> errors.txt` ## Parse the Cluster Identifier, append the region to each line delimited by a comma and output to the CSV
do
emrclustconfig=`aws emr describe-cluster --cluster-id $emrclust --query 'Cluster.Ec2InstanceAttributes' --region $region --output json 2>> errors.txt` ## Get "true" for clusters that don't have a VPC subnet configured and "false" for ones that do have a subnet configured
emrsubnetid=`jq -r '.Ec2SubnetId' <<< $emrclustconfig 2>> errors.txt`
emrrequestedsubnetids=`jq -r '.RequestedEc2SubnetIds[]' <<< $emrclustconfig 2>> errors.txt`
if [[ ${#emrsubnetid} -lt 10 ]] && [[ ${#emrrequestedsubnetids} -lt 10 ]] ## If the cluster doesn't have a subnet configured then:
then printf "$profile,$region,$emrclust\n" >> Classic_EMR_Clusters.csv ## Return the Cluster ID and region and output it to a CSV
fi
unset emrsubnetid
unset emrrequestedsubnetids
unset emrclustconfig
done
unset emrclust
unset emrraw
emrloopcounter=$((emrloopcounter + 1))
done
printf "Done \xe2\x9c\x85 \n"
## Search for OpsWorks Stacks
printf "Searching for OpsWorks stacks with resources in EC2-Classic..."
[[ $header == 0 ]] || echo "profile,region,StackId" >> Classic_OpsWorks_Stacks.csv
aws opsworks describe-stacks --query 'Stacks[?VpcId==`null`]' --region $region --output json 2>> errors.txt \
| jq -r --arg profile "$profile" --arg region "$region" '.[] | [$profile, $region, .StackId] | @csv' >> Classic_OpsWorks_Stacks.csv ## Get all OpsWorks Stacks in EC2-Classic and output them with their corresponding region to a CSV
printf "Done \xe2\x9c\x85 \n"
## Unset all the variables we used within the region loop
unset classicstatus ec2next ec2loopcounter ec2raw sgnext sgloopcounter sgraw asgnext asgloopcounter \
asgraw clbnext clbloopcounter clbraw rdsnext rdsloopcounter rdsraw ecachenext ecacheloopcounter ecacheraw redshiftnext redshiftloopcounter redshiftraw ebappnext \
ebapploopcounter ebappraw ebenvapp ebapp ebenv ebnsval ebnsvalregex dpnext dploopcounter dpraw pipeline dpdefinition dpdefinitionregex emrnext emrloopcounter \
emrraw emrclust emrclustconfig emrsubnetid emrrequestedsubnetids
printf "\n# -------------------------------------------------------------------------\nSearch for resources in $region is complete\n# -------------------------------------------------------------------------\n\n\n\n"
if [ $i == 0 ]; then
header=0
i=$(($i+1))
fi
done
## Unset all the variables we used outside of and for the region loop
unset awscurrentversion awsversionregex jqtest cuttest region
printf "Search for EC2-Classic Resources is complete! Please check for the CSVs output to this directory."
printf "If no resources were found in EC2-Classic for a service, empty CSVs were created with no resources except for Classic_Platform_Status.csv which shows the current status of all regions."
printf "As a final step once you have verified you have no other EC2-Classic resources, "
printf "please open a support case and request your account be converted to VPC-Only as outlined in this document: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-migrate.html \n\n"