aws_recon 0.5.0 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/check-aws-regions.yml +18 -0
- data/aws_recon.gemspec +1 -1
- data/lib/aws_recon/collectors/ec2.rb +18 -18
- data/lib/aws_recon/collectors/iam.rb +1 -1
- data/lib/aws_recon/options.rb +2 -2
- data/lib/aws_recon/services.yaml +3 -12
- data/lib/aws_recon/version.rb +1 -1
- data/readme.md +5 -5
- data/utils/aws/check_region_exclusions.rb +112 -0
- data/utils/aws/regions.yaml +43 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7574ac2a2ffd096dae78183fe03998f59540d1f9672724b2e705894fc0fb5da
|
4
|
+
data.tar.gz: 1af2a00fa0e5a656f36b3966ada67b1c898763ecf2018a0dd087f2d7214d0506
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e00e5416344bd5964e43b81677c90e483b522d5b116c7607f08215d83037088f67d8bd614979d3d056506d1c8a940108cf97ef2e2dddd0566c593d52fb1f56b
|
7
|
+
data.tar.gz: 49903877096060c68333b68022a7badde671183775b08b03efcc16e4c8967ab148903bd69e9e9eb7a0860350acafbb051d3aee2186e68667c6ed9b4075212f2b
|
@@ -0,0 +1,18 @@
|
|
1
|
+
name: check-service-regions
|
2
|
+
|
3
|
+
on:
|
4
|
+
workflow_dispatch:
|
5
|
+
schedule:
|
6
|
+
- cron: '0 10 * * *'
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
region-check:
|
10
|
+
runs-on: ubuntu-20.04
|
11
|
+
steps:
|
12
|
+
- name: Checkout
|
13
|
+
uses: actions/checkout@v2
|
14
|
+
with:
|
15
|
+
fetch-depth: 1
|
16
|
+
- name: Check AWS service regions
|
17
|
+
run: |
|
18
|
+
cd utils/aws ; ruby check_region_exclusions.rb
|
data/aws_recon.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.name = 'aws_recon'
|
9
9
|
spec.version = AwsRecon::VERSION
|
10
10
|
spec.authors = ['Josh Larsen', 'Darkbit']
|
11
|
-
spec.required_ruby_version = '>= 2.
|
11
|
+
spec.required_ruby_version = '>= 2.6.0'
|
12
12
|
spec.summary = 'A multi-threaded AWS security-focused inventory collection tool.'
|
13
13
|
spec.description = 'AWS Recon is a command line tool to collect resources from an Amazon Web Services (AWS) account. The tool outputs JSON suitable for processing with other tools.'
|
14
14
|
spec.homepage = 'https://github.com/darkbitio/aws-recon'
|
@@ -29,7 +29,7 @@ class EC2 < Mapper
|
|
29
29
|
struct = OpenStruct.new
|
30
30
|
struct.attributes = response.account_attributes.map(&:to_h)
|
31
31
|
struct.type = 'account'
|
32
|
-
struct.arn = "arn:aws:ec2::#{@account}/account_attributes"
|
32
|
+
struct.arn = "arn:aws:ec2::#{@account}:attributes/account_attributes"
|
33
33
|
|
34
34
|
resources.push(struct.to_h)
|
35
35
|
end
|
@@ -45,7 +45,7 @@ class EC2 < Mapper
|
|
45
45
|
|
46
46
|
struct = OpenStruct.new(response.to_h)
|
47
47
|
struct.type = 'ebs_encryption_settings'
|
48
|
-
struct.arn = "arn:aws:ec2:#{@region}:#{@account}/ebs_encryption_settings"
|
48
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:settings/ebs_encryption_settings"
|
49
49
|
|
50
50
|
resources.push(struct.to_h)
|
51
51
|
end
|
@@ -64,7 +64,7 @@ class EC2 < Mapper
|
|
64
64
|
reservation.instances.each do |instance|
|
65
65
|
struct = OpenStruct.new(instance.to_h)
|
66
66
|
struct.type = 'instance'
|
67
|
-
struct.arn = instance.instance_id # no true ARN
|
67
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:instance/#{instance.instance_id}" # no true ARN
|
68
68
|
struct.reservation_id = reservation.reservation_id
|
69
69
|
|
70
70
|
# collect instance user_data
|
@@ -96,7 +96,7 @@ class EC2 < Mapper
|
|
96
96
|
response.vpcs.each do |vpc|
|
97
97
|
struct = OpenStruct.new(vpc.to_h)
|
98
98
|
struct.type = 'vpc'
|
99
|
-
struct.arn = "arn:aws:ec2:#{@region}:#{@account}/#{vpc.vpc_id}" # no true ARN
|
99
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:vpc/#{vpc.vpc_id}" # no true ARN
|
100
100
|
struct.flow_logs = @client
|
101
101
|
.describe_flow_logs({ filter: [{ name: 'resource-id', values: [vpc.vpc_id] }] })
|
102
102
|
.flow_logs.first.to_h
|
@@ -114,7 +114,7 @@ class EC2 < Mapper
|
|
114
114
|
response.security_groups.each do |security_group|
|
115
115
|
struct = OpenStruct.new(security_group.to_h)
|
116
116
|
struct.type = 'security_group'
|
117
|
-
struct.arn = "arn:aws:ec2:#{@region}:#{@account}/#{security_group.group_id}" # no true ARN
|
117
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:security_group/#{security_group.group_id}" # no true ARN
|
118
118
|
|
119
119
|
resources.push(struct.to_h)
|
120
120
|
end
|
@@ -129,7 +129,7 @@ class EC2 < Mapper
|
|
129
129
|
response.network_interfaces.each do |network_interface|
|
130
130
|
struct = OpenStruct.new(network_interface.to_h)
|
131
131
|
struct.type = 'network_interface'
|
132
|
-
struct.arn = "arn:aws:ec2:#{@region}:#{@account}/#{network_interface.network_interface_id}" # no true ARN
|
132
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:network_interface/#{network_interface.network_interface_id}" # no true ARN
|
133
133
|
|
134
134
|
resources.push(struct.to_h)
|
135
135
|
end
|
@@ -144,7 +144,7 @@ class EC2 < Mapper
|
|
144
144
|
response.network_acls.each do |network_acl|
|
145
145
|
struct = OpenStruct.new(network_acl.to_h)
|
146
146
|
struct.type = 'network_acl'
|
147
|
-
struct.arn = "arn:aws:ec2:#{@region}:#{@account}/#{network_acl.network_acl_id}" # no true ARN
|
147
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:network_acl/#{network_acl.network_acl_id}" # no true ARN
|
148
148
|
|
149
149
|
resources.push(struct.to_h)
|
150
150
|
end
|
@@ -159,7 +159,7 @@ class EC2 < Mapper
|
|
159
159
|
response.subnets.each do |subnet|
|
160
160
|
struct = OpenStruct.new(subnet.to_h)
|
161
161
|
struct.type = 'subnet'
|
162
|
-
struct.arn =
|
162
|
+
struct.arn = subnet.subnet_arn
|
163
163
|
|
164
164
|
resources.push(struct.to_h)
|
165
165
|
end
|
@@ -174,7 +174,7 @@ class EC2 < Mapper
|
|
174
174
|
response.addresses.each do |address|
|
175
175
|
struct = OpenStruct.new(address.to_h)
|
176
176
|
struct.type = 'eip_address'
|
177
|
-
struct.arn = "arn:aws:ec2:#{@region}:#{@account}/#{address.allocation_id}" # no true ARN
|
177
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:eip_address/#{address.allocation_id}" # no true ARN
|
178
178
|
|
179
179
|
resources.push(struct.to_h)
|
180
180
|
end
|
@@ -189,7 +189,7 @@ class EC2 < Mapper
|
|
189
189
|
response.nat_gateways.each do |gateway|
|
190
190
|
struct = OpenStruct.new(gateway.to_h)
|
191
191
|
struct.type = 'nat_gateway'
|
192
|
-
struct.arn = "arn:aws:ec2:#{@region}:#{@account}/#{gateway.nat_gateway_id}" # no true ARN
|
192
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:nat_gateway/#{gateway.nat_gateway_id}" # no true ARN
|
193
193
|
|
194
194
|
resources.push(struct.to_h)
|
195
195
|
end
|
@@ -204,7 +204,7 @@ class EC2 < Mapper
|
|
204
204
|
response.internet_gateways.each do |gateway|
|
205
205
|
struct = OpenStruct.new(gateway.to_h)
|
206
206
|
struct.type = 'internet_gateway'
|
207
|
-
struct.arn = "arn:aws:ec2:#{@region}:#{@account}/#{gateway.internet_gateway_id}" # no true ARN
|
207
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:internet_gateway/#{gateway.internet_gateway_id}" # no true ARN
|
208
208
|
|
209
209
|
resources.push(struct.to_h)
|
210
210
|
end
|
@@ -219,7 +219,7 @@ class EC2 < Mapper
|
|
219
219
|
response.route_tables.each do |table|
|
220
220
|
struct = OpenStruct.new(table.to_h)
|
221
221
|
struct.type = 'route_table'
|
222
|
-
struct.arn = "arn:aws:ec2:#{@region}:#{@account}/#{table.route_table_id}" # no true ARN
|
222
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:route_table/#{table.route_table_id}" # no true ARN
|
223
223
|
|
224
224
|
resources.push(struct.to_h)
|
225
225
|
end
|
@@ -234,7 +234,7 @@ class EC2 < Mapper
|
|
234
234
|
response.images.each do |image|
|
235
235
|
struct = OpenStruct.new(image.to_h)
|
236
236
|
struct.type = 'image'
|
237
|
-
struct.arn = "arn:aws:ec2:#{@region}:#{@account}/#{image.image_id}" # no true ARN
|
237
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:image/#{image.image_id}" # no true ARN
|
238
238
|
|
239
239
|
resources.push(struct.to_h)
|
240
240
|
end
|
@@ -249,7 +249,7 @@ class EC2 < Mapper
|
|
249
249
|
response.snapshots.each do |snapshot|
|
250
250
|
struct = OpenStruct.new(snapshot.to_h)
|
251
251
|
struct.type = 'snapshot'
|
252
|
-
struct.arn = "arn:aws:ec2:#{@region}:#{@account}/#{snapshot.snapshot_id}" # no true ARN
|
252
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:snapshot/#{snapshot.snapshot_id}" # no true ARN
|
253
253
|
struct.create_volume_permissions = @client.describe_snapshot_attribute({
|
254
254
|
attribute: 'createVolumePermission',
|
255
255
|
snapshot_id: snapshot.snapshot_id
|
@@ -268,7 +268,7 @@ class EC2 < Mapper
|
|
268
268
|
response.flow_logs.each do |flow_log|
|
269
269
|
struct = OpenStruct.new(flow_log.to_h)
|
270
270
|
struct.type = 'flow_log'
|
271
|
-
struct.arn = "arn:aws:ec2:#{@region}:#{@account}/#{flow_log.flow_log_id}" # no true ARN
|
271
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:flow_log/#{flow_log.flow_log_id}" # no true ARN
|
272
272
|
|
273
273
|
resources.push(struct.to_h)
|
274
274
|
end
|
@@ -283,7 +283,7 @@ class EC2 < Mapper
|
|
283
283
|
response.volumes.each do |volume|
|
284
284
|
struct = OpenStruct.new(volume.to_h)
|
285
285
|
struct.type = 'volume'
|
286
|
-
struct.arn = "arn:aws:ec2:#{@region}:#{@account}/#{volume.volume_id}" # no true ARN
|
286
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:volume/#{volume.volume_id}" # no true ARN
|
287
287
|
|
288
288
|
resources.push(struct.to_h)
|
289
289
|
end
|
@@ -298,7 +298,7 @@ class EC2 < Mapper
|
|
298
298
|
response.vpn_gateways.each do |gateway|
|
299
299
|
struct = OpenStruct.new(gateway.to_h)
|
300
300
|
struct.type = 'vpn_gateway'
|
301
|
-
struct.arn = "arn:aws:ec2:#{@region}:#{@account}/#{gateway.vpn_gateway_id}" # no true ARN
|
301
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:vpn_gateway/#{gateway.vpn_gateway_id}" # no true ARN
|
302
302
|
|
303
303
|
resources.push(struct.to_h)
|
304
304
|
end
|
@@ -313,7 +313,7 @@ class EC2 < Mapper
|
|
313
313
|
response.vpc_peering_connections.each do |peer|
|
314
314
|
struct = OpenStruct.new(peer.to_h)
|
315
315
|
struct.type = 'peering_connection'
|
316
|
-
struct.arn = "arn:aws:ec2:#{@region}:#{@account}/#{peer.vpc_peering_connection_id}" # no true ARN
|
316
|
+
struct.arn = "arn:aws:ec2:#{@region}:#{@account}:peering_connection/#{peer.vpc_peering_connection_id}" # no true ARN
|
317
317
|
|
318
318
|
resources.push(struct.to_h)
|
319
319
|
end
|
data/lib/aws_recon/options.rb
CHANGED
@@ -36,8 +36,8 @@ class Parser
|
|
36
36
|
aws_regions = ['global'].concat(Aws::EC2::Client.new.describe_regions.regions.map(&:region_name))
|
37
37
|
end
|
38
38
|
rescue Aws::Errors::ServiceError => e
|
39
|
-
|
40
|
-
exit
|
39
|
+
warn "\nAWS Error: #{e.code}\n\n"
|
40
|
+
exit(1)
|
41
41
|
end
|
42
42
|
|
43
43
|
aws_services = YAML.load(File.read(SERVICES_CONFIG_FILE), symbolize_names: true)
|
data/lib/aws_recon/services.yaml
CHANGED
@@ -37,8 +37,6 @@
|
|
37
37
|
alias: ecs
|
38
38
|
- name: ElasticLoadBalancing
|
39
39
|
alias: elb
|
40
|
-
excluded_regions:
|
41
|
-
- ap-southeast-1
|
42
40
|
- name: ElasticLoadBalancingV2
|
43
41
|
alias: elbv2
|
44
42
|
- name: ElastiCache
|
@@ -85,15 +83,15 @@
|
|
85
83
|
- name: Shield
|
86
84
|
global: true
|
87
85
|
alias: shield
|
86
|
+
excluded_regions:
|
87
|
+
- ap-northeast-3
|
88
88
|
- name: CloudFormation
|
89
89
|
alias: cloudformation
|
90
90
|
- name: SES
|
91
91
|
alias: ses
|
92
92
|
excluded_regions:
|
93
|
-
- af-south-1
|
94
93
|
- ap-east-1
|
95
94
|
- ap-northeast-3
|
96
|
-
- eu-south-1
|
97
95
|
- name: CloudWatch
|
98
96
|
alias: cloudwatch
|
99
97
|
- name: CloudWatchLogs
|
@@ -106,9 +104,7 @@
|
|
106
104
|
- name: SecretsManager
|
107
105
|
alias: sm
|
108
106
|
- name: SecurityHub
|
109
|
-
alias:
|
110
|
-
excluded_regions:
|
111
|
-
- ap-northeast-3
|
107
|
+
alias: securityhub
|
112
108
|
- name: Support
|
113
109
|
global: true
|
114
110
|
alias: support
|
@@ -116,16 +112,12 @@
|
|
116
112
|
alias: ssm
|
117
113
|
- name: GuardDuty
|
118
114
|
alias: guardduty
|
119
|
-
excluded_regions:
|
120
|
-
- ap-northeast-3
|
121
115
|
- name: Athena
|
122
116
|
alias: athena
|
123
117
|
excluded_regions:
|
124
118
|
- ap-northeast-3
|
125
119
|
- name: EFS
|
126
120
|
alias: efs
|
127
|
-
excluded_regions:
|
128
|
-
- ap-northeast-3
|
129
121
|
- name: Firehose
|
130
122
|
alias: firehose
|
131
123
|
- name: Lightsail
|
@@ -145,7 +137,6 @@
|
|
145
137
|
- af-south-1
|
146
138
|
- ap-east-1
|
147
139
|
- ap-northeast-3
|
148
|
-
- ap-south-1
|
149
140
|
- eu-north-1
|
150
141
|
- eu-south-1
|
151
142
|
- eu-west-3
|
data/lib/aws_recon/version.rb
CHANGED
data/readme.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
[](https://github.com/darkbitio/aws-recon/actions?query=branch%3Amain)
|
2
2
|
[](https://rubygems.org/gems/aws_recon)
|
3
|
-
|
3
|
+
[](https://github.com/darkbitio/aws-recon/actions/workflows/check-aws-regions.yml)
|
4
4
|
# AWS Recon
|
5
5
|
|
6
6
|
A multi-threaded AWS security-focused inventory collection tool written in Ruby.
|
@@ -54,13 +54,13 @@ To run locally, first install the gem:
|
|
54
54
|
|
55
55
|
```
|
56
56
|
$ gem install aws_recon
|
57
|
-
Fetching aws_recon-0.
|
57
|
+
Fetching aws_recon-0.5.2.gem
|
58
58
|
Fetching aws-sdk-3.0.1.gem
|
59
59
|
Fetching parallel-1.20.1.gem
|
60
60
|
...
|
61
61
|
Successfully installed aws-sdk-3.0.1
|
62
62
|
Successfully installed parallel-1.20.1
|
63
|
-
Successfully installed aws_recon-0.
|
63
|
+
Successfully installed aws_recon-0.5.2
|
64
64
|
```
|
65
65
|
|
66
66
|
Or add it to your Gemfile using `bundle`:
|
@@ -72,7 +72,7 @@ Resolving dependencies...
|
|
72
72
|
...
|
73
73
|
Using aws-sdk 3.0.1
|
74
74
|
Using parallel-1.20.1
|
75
|
-
Using aws_recon 0.
|
75
|
+
Using aws_recon 0.5.2
|
76
76
|
```
|
77
77
|
|
78
78
|
## Usage
|
@@ -249,7 +249,7 @@ Most users will want to limit collection to relevant services and regions. Runni
|
|
249
249
|
```
|
250
250
|
$ aws_recon -h
|
251
251
|
|
252
|
-
AWS Recon - AWS Inventory Collector (0.
|
252
|
+
AWS Recon - AWS Inventory Collector (0.5.2)
|
253
253
|
|
254
254
|
Usage: aws_recon [options]
|
255
255
|
-r, --regions [REGIONS] Regions to scan, separated by comma (default: all)
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Check regional service availability against services.yaml exclusions.
|
5
|
+
#
|
6
|
+
# AWS updates the regional service table daily. By checking regional service
|
7
|
+
# coverage, we can identify regions that should be excluded from AWS Recon
|
8
|
+
# checks. We exclude non-supported regions because service APIs handle non-
|
9
|
+
# availability differently. Some will respond with an error that can be handled
|
10
|
+
# by the errors defined in the AWS Ruby SDK client. Others will fail at the
|
11
|
+
# network level (i.e. there is no API endpoint even available). We could handle
|
12
|
+
# those errors and silently fail, but we choose not to so we can identify cases
|
13
|
+
# where there is a lack of service availability in a particular region.
|
14
|
+
#
|
15
|
+
require 'net/http'
|
16
|
+
require 'json'
|
17
|
+
require 'yaml'
|
18
|
+
|
19
|
+
TS = Time.now.to_i
|
20
|
+
# AWS Regional services table
|
21
|
+
URL = "https://api.regional-table.region-services.aws.a2z.com/index.json?timestamp=#{TS}000"
|
22
|
+
|
23
|
+
service_to_query = ARGV[0]
|
24
|
+
region_exclusion_mistmatch = nil
|
25
|
+
|
26
|
+
#
|
27
|
+
# load current AWS Recon regions
|
28
|
+
#
|
29
|
+
recon_services = YAML.safe_load(File.read('../../lib/aws_recon/services.yaml'))
|
30
|
+
abort('Errors loading AWS Recon services') unless recon_services.is_a?(Array)
|
31
|
+
|
32
|
+
#
|
33
|
+
# load current AWS regions (non-gov, non-cn)
|
34
|
+
#
|
35
|
+
regions = YAML.safe_load(File.read('regions.yaml'))
|
36
|
+
abort('Errors loading regions') unless regions['Regions']
|
37
|
+
|
38
|
+
all_regions = regions['Regions'].map { |r| r['RegionName'] }
|
39
|
+
|
40
|
+
#
|
41
|
+
# get service/price list from AWS
|
42
|
+
#
|
43
|
+
uri = URI(URL)
|
44
|
+
res = Net::HTTP.get_response(uri)
|
45
|
+
abort('Error loading AWS services from API') unless res.code == '200'
|
46
|
+
|
47
|
+
map = {}
|
48
|
+
|
49
|
+
#
|
50
|
+
# load service region availability
|
51
|
+
#
|
52
|
+
data = res.body
|
53
|
+
json = JSON.parse(data)
|
54
|
+
|
55
|
+
#
|
56
|
+
# query regions for a single service
|
57
|
+
#
|
58
|
+
if service_to_query
|
59
|
+
single_service_regions = []
|
60
|
+
|
61
|
+
json['prices'].each do |p|
|
62
|
+
single_service_regions << p['id'].split(':').last
|
63
|
+
end
|
64
|
+
|
65
|
+
single_service_regions.uniq.sort.each { |r| puts r }
|
66
|
+
|
67
|
+
exit 0
|
68
|
+
end
|
69
|
+
|
70
|
+
# iterate through AWS provided services & regions
|
71
|
+
json['prices'].each do |p|
|
72
|
+
at = p['attributes']
|
73
|
+
service_name = at['aws:serviceName']
|
74
|
+
service_id, service_region = p['id'].split(':')
|
75
|
+
|
76
|
+
# skip this service unless AWS Recon already has exclusions
|
77
|
+
next unless recon_services.filter { |s| s['alias'] == service_id }&.length&.positive?
|
78
|
+
|
79
|
+
if map.key?(service_name)
|
80
|
+
map[service_name]['regions'] << service_region
|
81
|
+
else
|
82
|
+
map[service_name] = {
|
83
|
+
'id' => service_id,
|
84
|
+
'regions' => [service_region]
|
85
|
+
}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# iterate through the services AWS Recon knows about
|
90
|
+
map.sort.each do |k, v|
|
91
|
+
service_excluded_regions = all_regions.reject { |r| v['regions'].include?(r) }
|
92
|
+
|
93
|
+
aws_recon_service = recon_services.filter { |s| s['alias'] == v['id'] }&.first
|
94
|
+
aws_recon_service_excluded_regions = aws_recon_service['excluded_regions'] || []
|
95
|
+
|
96
|
+
# move on if AWS Recon region exclusions match AWS service region exclusions
|
97
|
+
next unless service_excluded_regions.sort != aws_recon_service_excluded_regions.sort
|
98
|
+
|
99
|
+
region_exclusion_mistmatch = true
|
100
|
+
|
101
|
+
puts "#{k} (#{v['id']})"
|
102
|
+
|
103
|
+
# determine the direction of the exclusion mismatch
|
104
|
+
if (service_excluded_regions - aws_recon_service_excluded_regions).length.positive?
|
105
|
+
puts " + missing region exclusion: #{(service_excluded_regions - aws_recon_service_excluded_regions).join(', ')}"
|
106
|
+
else
|
107
|
+
puts " - unnecessary region exclusion: #{(aws_recon_service_excluded_regions - service_excluded_regions).join(', ')}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# exit code 1 if we have any mismatches
|
112
|
+
exit 1 if region_exclusion_mistmatch
|
@@ -0,0 +1,43 @@
|
|
1
|
+
Regions:
|
2
|
+
- Endpoint: ec2.af-south-1.amazonaws.com
|
3
|
+
RegionName: af-south-1
|
4
|
+
- Endpoint: ec2.eu-north-1.amazonaws.com
|
5
|
+
RegionName: eu-north-1
|
6
|
+
- Endpoint: ec2.ap-south-1.amazonaws.com
|
7
|
+
RegionName: ap-south-1
|
8
|
+
- Endpoint: ec2.eu-west-3.amazonaws.com
|
9
|
+
RegionName: eu-west-3
|
10
|
+
- Endpoint: ec2.eu-west-2.amazonaws.com
|
11
|
+
RegionName: eu-west-2
|
12
|
+
- Endpoint: ec2.eu-south-1.amazonaws.com
|
13
|
+
RegionName: eu-south-1
|
14
|
+
- Endpoint: ec2.eu-west-1.amazonaws.com
|
15
|
+
RegionName: eu-west-1
|
16
|
+
- Endpoint: ec2.ap-northeast-3.amazonaws.com
|
17
|
+
RegionName: ap-northeast-3
|
18
|
+
- Endpoint: ec2.ap-northeast-2.amazonaws.com
|
19
|
+
RegionName: ap-northeast-2
|
20
|
+
- Endpoint: ec2.me-south-1.amazonaws.com
|
21
|
+
RegionName: me-south-1
|
22
|
+
- Endpoint: ec2.ap-northeast-1.amazonaws.com
|
23
|
+
RegionName: ap-northeast-1
|
24
|
+
- Endpoint: ec2.sa-east-1.amazonaws.com
|
25
|
+
RegionName: sa-east-1
|
26
|
+
- Endpoint: ec2.ca-central-1.amazonaws.com
|
27
|
+
RegionName: ca-central-1
|
28
|
+
- Endpoint: ec2.ap-east-1.amazonaws.com
|
29
|
+
RegionName: ap-east-1
|
30
|
+
- Endpoint: ec2.ap-southeast-1.amazonaws.com
|
31
|
+
RegionName: ap-southeast-1
|
32
|
+
- Endpoint: ec2.ap-southeast-2.amazonaws.com
|
33
|
+
RegionName: ap-southeast-2
|
34
|
+
- Endpoint: ec2.eu-central-1.amazonaws.com
|
35
|
+
RegionName: eu-central-1
|
36
|
+
- Endpoint: ec2.us-east-1.amazonaws.com
|
37
|
+
RegionName: us-east-1
|
38
|
+
- Endpoint: ec2.us-east-2.amazonaws.com
|
39
|
+
RegionName: us-east-2
|
40
|
+
- Endpoint: ec2.us-west-1.amazonaws.com
|
41
|
+
RegionName: us-west-1
|
42
|
+
- Endpoint: ec2.us-west-2.amazonaws.com
|
43
|
+
RegionName: us-west-2
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws_recon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Larsen
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-04-
|
12
|
+
date: 2021-04-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk
|
@@ -163,6 +163,7 @@ extensions: []
|
|
163
163
|
extra_rdoc_files: []
|
164
164
|
files:
|
165
165
|
- ".github/stale.yml"
|
166
|
+
- ".github/workflows/check-aws-regions.yml"
|
166
167
|
- ".github/workflows/docker-build.yml"
|
167
168
|
- ".github/workflows/smoke-test.yml"
|
168
169
|
- ".gitignore"
|
@@ -245,6 +246,8 @@ files:
|
|
245
246
|
- lib/aws_recon/services.yaml
|
246
247
|
- lib/aws_recon/version.rb
|
247
248
|
- readme.md
|
249
|
+
- utils/aws/check_region_exclusions.rb
|
250
|
+
- utils/aws/regions.yaml
|
248
251
|
- utils/cloudformation/aws-recon-cfn-template.yml
|
249
252
|
- utils/terraform/cloudwatch.tf
|
250
253
|
- utils/terraform/ecs.tf
|
@@ -267,7 +270,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
267
270
|
requirements:
|
268
271
|
- - ">="
|
269
272
|
- !ruby/object:Gem::Version
|
270
|
-
version: 2.
|
273
|
+
version: 2.6.0
|
271
274
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
272
275
|
requirements:
|
273
276
|
- - ">="
|