cfn-vpn 1.1.1 → 1.3.3
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/Gemfile.lock +21 -19
- data/cfn-vpn.gemspec +1 -0
- data/docs/README.md +2 -2
- data/docs/getting-started.md +84 -29
- data/docs/routes.md +34 -20
- data/lib/cfnvpn/actions/init.rb +28 -12
- data/lib/cfnvpn/actions/modify.rb +21 -1
- data/lib/cfnvpn/actions/routes.rb +60 -8
- data/lib/cfnvpn/clientvpn.rb +18 -0
- data/lib/cfnvpn/s3.rb +30 -0
- data/lib/cfnvpn/s3_bucket.rb +48 -0
- data/lib/cfnvpn/string.rb +4 -0
- data/lib/cfnvpn/templates/lambdas/auto_route_populator/app.py +175 -0
- data/lib/cfnvpn/templates/lambdas/scheduler/app.py +36 -0
- data/lib/cfnvpn/templates/lambdas.rb +35 -0
- data/lib/cfnvpn/templates/vpn.rb +198 -93
- data/lib/cfnvpn/version.rb +1 -1
- metadata +21 -3
data/lib/cfnvpn/templates/vpn.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'cfndsl'
|
|
2
2
|
require 'cfnvpn/templates/helper'
|
|
3
|
+
require 'cfnvpn/templates/lambdas'
|
|
3
4
|
|
|
4
5
|
module CfnVpn
|
|
5
6
|
module Templates
|
|
@@ -32,10 +33,17 @@ module CfnVpn
|
|
|
32
33
|
{
|
|
33
34
|
FederatedAuthentication: {
|
|
34
35
|
SAMLProviderArn: config[:saml_arn],
|
|
35
|
-
SelfServiceSAMLProviderArn: config[:saml_arn]
|
|
36
|
+
SelfServiceSAMLProviderArn: config[:saml_self_service_arn].nil? ? config[:saml_arn] : config[:saml_self_service_arn]
|
|
36
37
|
},
|
|
37
38
|
Type: 'federated-authentication'
|
|
38
39
|
}
|
|
40
|
+
elsif config[:type] == 'active-directory'
|
|
41
|
+
{
|
|
42
|
+
ActiveDirectory: {
|
|
43
|
+
DirectoryId: config[:directory_id]
|
|
44
|
+
},
|
|
45
|
+
Type: 'directory-service-authentication'
|
|
46
|
+
}
|
|
39
47
|
else
|
|
40
48
|
{
|
|
41
49
|
MutualAuthentication: {
|
|
@@ -62,6 +70,7 @@ module CfnVpn
|
|
|
62
70
|
SplitTunnel config[:split_tunnel]
|
|
63
71
|
}
|
|
64
72
|
|
|
73
|
+
network_assoc_dependson = []
|
|
65
74
|
config[:subnet_ids].each_with_index do |subnet, index|
|
|
66
75
|
suffix = index == 0 ? "" : "For#{subnet.resource_safe}"
|
|
67
76
|
|
|
@@ -71,74 +80,112 @@ module CfnVpn
|
|
|
71
80
|
SubnetId subnet
|
|
72
81
|
}
|
|
73
82
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
AccessGroupId group
|
|
81
|
-
ClientVpnEndpointId Ref(:ClientVpnEndpoint)
|
|
82
|
-
TargetNetworkCidr CfnVpn::Templates::Helper.get_auth_cidr(config[:region], subnet)
|
|
83
|
-
}
|
|
84
|
-
end
|
|
85
|
-
else
|
|
86
|
-
EC2_ClientVpnAuthorizationRule(:"TargetNetworkAuthorizationRule#{suffix}") {
|
|
83
|
+
network_assoc_dependson << "ClientVpnTargetNetworkAssociation#{suffix}"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
if config[:default_groups].any?
|
|
87
|
+
config[:default_groups].each do |group|
|
|
88
|
+
EC2_ClientVpnAuthorizationRule(:"TargetNetworkAuthorizationRule#{group.resource_safe}"[0..255]) {
|
|
87
89
|
Condition(:EnableSubnetAssociation)
|
|
88
|
-
DependsOn
|
|
90
|
+
DependsOn network_assoc_dependson if network_assoc_dependson.any?
|
|
89
91
|
Description FnSub("#{name} client-vpn auth rule for subnet association")
|
|
90
|
-
|
|
92
|
+
AccessGroupId group
|
|
91
93
|
ClientVpnEndpointId Ref(:ClientVpnEndpoint)
|
|
92
|
-
TargetNetworkCidr CfnVpn::Templates::Helper.get_auth_cidr(config[:region],
|
|
94
|
+
TargetNetworkCidr CfnVpn::Templates::Helper.get_auth_cidr(config[:region], config[:subnet_ids].first)
|
|
93
95
|
}
|
|
94
96
|
end
|
|
97
|
+
else
|
|
98
|
+
EC2_ClientVpnAuthorizationRule(:"TargetNetworkAuthorizationRule") {
|
|
99
|
+
Condition(:EnableSubnetAssociation)
|
|
100
|
+
DependsOn network_assoc_dependson if network_assoc_dependson.any?
|
|
101
|
+
Description FnSub("#{name} client-vpn auth rule for subnet association")
|
|
102
|
+
AuthorizeAllGroups true
|
|
103
|
+
ClientVpnEndpointId Ref(:ClientVpnEndpoint)
|
|
104
|
+
TargetNetworkCidr CfnVpn::Templates::Helper.get_auth_cidr(config[:region], config[:subnet_ids].first)
|
|
105
|
+
}
|
|
106
|
+
end
|
|
95
107
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
108
|
+
if !config[:internet_route].nil?
|
|
109
|
+
EC2_ClientVpnRoute(:RouteToInternet) {
|
|
110
|
+
Condition(:EnableSubnetAssociation)
|
|
111
|
+
DependsOn network_assoc_dependson if network_assoc_dependson.any?
|
|
112
|
+
Description "Route to the internet through subnet #{config[:internet_route]}"
|
|
113
|
+
ClientVpnEndpointId Ref(:ClientVpnEndpoint)
|
|
114
|
+
DestinationCidrBlock '0.0.0.0/0'
|
|
115
|
+
TargetVpcSubnetId config[:internet_route]
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
EC2_ClientVpnAuthorizationRule(:RouteToInternetAuthorizationRule) {
|
|
119
|
+
Condition(:EnableSubnetAssociation)
|
|
120
|
+
DependsOn network_assoc_dependson if network_assoc_dependson.any?
|
|
121
|
+
Description "Internet route authorization from subnet #{config[:internet_route]}"
|
|
122
|
+
AuthorizeAllGroups true
|
|
123
|
+
ClientVpnEndpointId Ref(:ClientVpnEndpoint)
|
|
124
|
+
TargetNetworkCidr '0.0.0.0/0'
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
output(:InternetRoute, config[:internet_route])
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
dns_routes = config[:routes].select {|route| route.has_key?(:dns)}
|
|
131
|
+
cidr_routes = config[:routes].select {|route| route.has_key?(:cidr)}
|
|
132
|
+
|
|
133
|
+
if dns_routes.any?
|
|
134
|
+
auto_route_populator(name, config[:bucket])
|
|
135
|
+
|
|
136
|
+
dns_routes.each do |route|
|
|
137
|
+
input = {
|
|
138
|
+
Record: route[:dns],
|
|
139
|
+
ClientVpnEndpointId: "${ClientVpnEndpoint}",
|
|
140
|
+
TargetSubnet: route[:subnet],
|
|
141
|
+
Description: route[:desc]
|
|
104
142
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
143
|
+
|
|
144
|
+
if route[:groups].any?
|
|
145
|
+
input[:Groups] = route[:groups]
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
Events_Rule(:"CfnVpnAutoRoutePopulatorEvent#{route[:dns].resource_safe}"[0..255]) {
|
|
149
|
+
State 'ENABLED'
|
|
150
|
+
Description "cfnvpn auto route populator schedule for #{route[:dns]}"
|
|
151
|
+
ScheduleExpression "rate(5 minutes)"
|
|
152
|
+
Targets([
|
|
153
|
+
{
|
|
154
|
+
Arn: FnGetAtt(:CfnVpnAutoRoutePopulator, :Arn),
|
|
155
|
+
Id: "cfnvpnautoroutepopulator#{route[:dns].event_id_safe}",
|
|
156
|
+
Input: FnSub(input.to_json)
|
|
157
|
+
}
|
|
158
|
+
])
|
|
113
159
|
}
|
|
114
|
-
|
|
115
|
-
output(:InternetRoute, config[:internet_route])
|
|
116
160
|
end
|
|
117
161
|
end
|
|
118
162
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
163
|
+
if cidr_routes.any?
|
|
164
|
+
cidr_routes.each do |route|
|
|
165
|
+
EC2_ClientVpnRoute(:"#{route[:cidr].resource_safe}VpnRoute") {
|
|
166
|
+
Description "cfnvpn static route for #{route[:cidr]}. #{route[:desc]}".strip
|
|
167
|
+
ClientVpnEndpointId Ref(:ClientVpnEndpoint)
|
|
168
|
+
DestinationCidrBlock route[:cidr]
|
|
169
|
+
TargetVpcSubnetId route[:subnet]
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if route[:groups].any?
|
|
173
|
+
route[:groups].each do |group|
|
|
174
|
+
EC2_ClientVpnAuthorizationRule(:"#{route[:cidr].resource_safe}AuthorizationRule#{group.resource_safe}"[0..255]) {
|
|
175
|
+
Description "cfnvpn static authorization rule for group #{group} to route #{route[:cidr]}. #{route[:desc]}".strip
|
|
176
|
+
AccessGroupId group
|
|
177
|
+
ClientVpnEndpointId Ref(:ClientVpnEndpoint)
|
|
178
|
+
TargetNetworkCidr route[:cidr]
|
|
179
|
+
}
|
|
180
|
+
end
|
|
181
|
+
else
|
|
182
|
+
EC2_ClientVpnAuthorizationRule(:"#{route[:cidr].resource_safe}AllowAllAuthorizationRule") {
|
|
183
|
+
Description "cfnvpn static allow all authorization rule to route #{route[:cidr]}. #{route[:desc]}".strip
|
|
184
|
+
AuthorizeAllGroups true
|
|
131
185
|
ClientVpnEndpointId Ref(:ClientVpnEndpoint)
|
|
132
186
|
TargetNetworkCidr route[:cidr]
|
|
133
187
|
}
|
|
134
188
|
end
|
|
135
|
-
else
|
|
136
|
-
EC2_ClientVpnAuthorizationRule(:"#{route[:cidr].resource_safe}AllowAllAuthorizationRule") {
|
|
137
|
-
Description route[:desc]
|
|
138
|
-
AuthorizeAllGroups true
|
|
139
|
-
ClientVpnEndpointId Ref(:ClientVpnEndpoint)
|
|
140
|
-
TargetNetworkCidr route[:cidr]
|
|
141
|
-
}
|
|
142
189
|
end
|
|
143
190
|
end
|
|
144
191
|
|
|
@@ -149,13 +196,13 @@ module CfnVpn
|
|
|
149
196
|
Type 'String'
|
|
150
197
|
Value config.to_json
|
|
151
198
|
Tags({
|
|
152
|
-
Name:
|
|
199
|
+
Name: "#{name}-cfnvpn-config",
|
|
153
200
|
Environment: 'cfnvpn'
|
|
154
201
|
})
|
|
155
202
|
}
|
|
156
203
|
|
|
157
204
|
if config[:start] || config[:stop]
|
|
158
|
-
scheduler(name, config[:start], config[:stop])
|
|
205
|
+
scheduler(name, config[:start], config[:stop], config[:bucket])
|
|
159
206
|
output(:Start, config[:start]) if config[:start]
|
|
160
207
|
output(:Stop, config[:stop]) if config[:stop]
|
|
161
208
|
end
|
|
@@ -170,6 +217,8 @@ module CfnVpn
|
|
|
170
217
|
|
|
171
218
|
if config[:type] == 'federated'
|
|
172
219
|
output(:SamlArn, config[:saml_arn])
|
|
220
|
+
elsif config[:type] == 'active-directory'
|
|
221
|
+
output(:DirectoryId, config[:directory_id])
|
|
173
222
|
else
|
|
174
223
|
output(:ClientCertArn, config[:client_cert_arn])
|
|
175
224
|
end
|
|
@@ -179,7 +228,92 @@ module CfnVpn
|
|
|
179
228
|
Output(name) { Value value }
|
|
180
229
|
end
|
|
181
230
|
|
|
182
|
-
def
|
|
231
|
+
def auto_route_populator(name, bucket)
|
|
232
|
+
IAM_Role(:CfnVpnAutoRoutePopulatorRole) {
|
|
233
|
+
AssumeRolePolicyDocument({
|
|
234
|
+
Version: '2012-10-17',
|
|
235
|
+
Statement: [{
|
|
236
|
+
Effect: 'Allow',
|
|
237
|
+
Principal: { Service: [ 'lambda.amazonaws.com' ] },
|
|
238
|
+
Action: [ 'sts:AssumeRole' ]
|
|
239
|
+
}]
|
|
240
|
+
})
|
|
241
|
+
Path '/cfnvpn/'
|
|
242
|
+
Policies([
|
|
243
|
+
{
|
|
244
|
+
PolicyName: 'client-vpn',
|
|
245
|
+
PolicyDocument: {
|
|
246
|
+
Version: '2012-10-17',
|
|
247
|
+
Statement: [{
|
|
248
|
+
Effect: 'Allow',
|
|
249
|
+
Action: [
|
|
250
|
+
'ec2:AuthorizeClientVpnIngress',
|
|
251
|
+
'ec2:RevokeClientVpnIngress',
|
|
252
|
+
'ec2:DescribeClientVpnAuthorizationRules',
|
|
253
|
+
'ec2:DescribeClientVpnEndpoints',
|
|
254
|
+
'ec2:DescribeClientVpnRoutes',
|
|
255
|
+
'ec2:CreateClientVpnRoute',
|
|
256
|
+
'ec2:DeleteClientVpnRoute'
|
|
257
|
+
],
|
|
258
|
+
Resource: '*'
|
|
259
|
+
}]
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
PolicyName: 'logging',
|
|
264
|
+
PolicyDocument: {
|
|
265
|
+
Version: '2012-10-17',
|
|
266
|
+
Statement: [{
|
|
267
|
+
Effect: 'Allow',
|
|
268
|
+
Action: [
|
|
269
|
+
'logs:DescribeLogGroups',
|
|
270
|
+
'logs:CreateLogGroup',
|
|
271
|
+
'logs:CreateLogStream',
|
|
272
|
+
'logs:DescribeLogStreams',
|
|
273
|
+
'logs:PutLogEvents'
|
|
274
|
+
],
|
|
275
|
+
Resource: '*'
|
|
276
|
+
}]
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
])
|
|
280
|
+
Tags([
|
|
281
|
+
{ Key: 'Name', Value: "#{name}-cfnvpn-auto-route-populator-role" },
|
|
282
|
+
{ Key: 'Environment', Value: 'cfnvpn' }
|
|
283
|
+
])
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
s3_key = CfnVpn::Templates::Lambdas.package_lambda(name: name, bucket: bucket, func: 'auto_route_populator', files: ['app.py'])
|
|
287
|
+
|
|
288
|
+
Lambda_Function(:CfnVpnAutoRoutePopulator) {
|
|
289
|
+
Runtime 'python3.8'
|
|
290
|
+
Role FnGetAtt(:CfnVpnAutoRoutePopulatorRole, :Arn)
|
|
291
|
+
MemorySize '128'
|
|
292
|
+
Handler 'app.handler'
|
|
293
|
+
Timeout 60
|
|
294
|
+
Code({
|
|
295
|
+
S3Bucket: bucket,
|
|
296
|
+
S3Key: s3_key
|
|
297
|
+
})
|
|
298
|
+
Tags([
|
|
299
|
+
{ Key: 'Name', Value: "#{name}-cfnvpn-auto-route-populator" },
|
|
300
|
+
{ Key: 'Environment', Value: 'cfnvpn' }
|
|
301
|
+
])
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
Logs_LogGroup(:CfnVpnAutoRoutePopulatorLogGroup) {
|
|
305
|
+
LogGroupName FnSub("/aws/lambda/${CfnVpnAutoRoutePopulator}")
|
|
306
|
+
RetentionInDays 30
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
Lambda_Permission(:CfnVpnAutoRoutePopulatorFunctionPermissions) {
|
|
310
|
+
FunctionName Ref(:CfnVpnAutoRoutePopulator)
|
|
311
|
+
Action 'lambda:InvokeFunction'
|
|
312
|
+
Principal 'events.amazonaws.com'
|
|
313
|
+
}
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
def scheduler(name, start, stop, bucket)
|
|
183
317
|
IAM_Role(:ClientVpnSchedulerRole) {
|
|
184
318
|
AssumeRolePolicyDocument({
|
|
185
319
|
Version: '2012-10-17',
|
|
@@ -249,46 +383,17 @@ module CfnVpn
|
|
|
249
383
|
])
|
|
250
384
|
}
|
|
251
385
|
|
|
386
|
+
s3_key = CfnVpn::Templates::Lambdas.package_lambda(name: name, bucket: bucket, func: 'scheduler', files: ['app.py'])
|
|
387
|
+
|
|
252
388
|
Lambda_Function(:ClientVpnSchedulerFunction) {
|
|
253
|
-
Runtime 'python3.
|
|
389
|
+
Runtime 'python3.8'
|
|
254
390
|
Role FnGetAtt(:ClientVpnSchedulerRole, :Arn)
|
|
255
391
|
MemorySize '128'
|
|
256
|
-
Handler '
|
|
392
|
+
Handler 'app.handler'
|
|
393
|
+
Timeout 60
|
|
257
394
|
Code({
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
def handler(event, context):
|
|
262
|
-
|
|
263
|
-
print(f"updating cfn-vpn stack {event['StackName']} parameter AssociateSubnets with value {event['AssociateSubnets']}")
|
|
264
|
-
|
|
265
|
-
if event['AssociateSubnets'] == 'false':
|
|
266
|
-
print(f"terminating current vpn sessions to {event['ClientVpnEndpointId']}")
|
|
267
|
-
ec2 = boto3.client('ec2')
|
|
268
|
-
resp = ec2.describe_client_vpn_connections(ClientVpnEndpointId=event['ClientVpnEndpointId'])
|
|
269
|
-
for conn in resp['Connections']:
|
|
270
|
-
if conn['Status']['Code'] == 'active':
|
|
271
|
-
ec2.terminate_client_vpn_connections(
|
|
272
|
-
ClientVpnEndpointId=event['ClientVpnEndpointId'],
|
|
273
|
-
ConnectionId=conn['ConnectionId']
|
|
274
|
-
)
|
|
275
|
-
print(f"terminated session {conn['ConnectionId']}")
|
|
276
|
-
|
|
277
|
-
client = boto3.client('cloudformation')
|
|
278
|
-
print(client.update_stack(
|
|
279
|
-
StackName=event['StackName'],
|
|
280
|
-
UsePreviousTemplate=True,
|
|
281
|
-
Capabilities=['CAPABILITY_IAM'],
|
|
282
|
-
Parameters=[
|
|
283
|
-
{
|
|
284
|
-
'ParameterKey': 'AssociateSubnets',
|
|
285
|
-
'ParameterValue': event['AssociateSubnets']
|
|
286
|
-
}
|
|
287
|
-
]
|
|
288
|
-
))
|
|
289
|
-
|
|
290
|
-
return 'OK'
|
|
291
|
-
EOS
|
|
395
|
+
S3Bucket: bucket,
|
|
396
|
+
S3Key: s3_key
|
|
292
397
|
})
|
|
293
398
|
Tags([
|
|
294
399
|
{ Key: 'Name', Value: "#{name}-cfnvpn-scheduler-function" },
|
data/lib/cfnvpn/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cfn-vpn
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Guslington
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-11-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: thor
|
|
@@ -78,6 +78,20 @@ dependencies:
|
|
|
78
78
|
- - '='
|
|
79
79
|
- !ruby/object:Gem::Version
|
|
80
80
|
version: 2.0.4
|
|
81
|
+
- !ruby/object:Gem::Dependency
|
|
82
|
+
name: rubyzip
|
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
|
84
|
+
requirements:
|
|
85
|
+
- - "~>"
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '2.3'
|
|
88
|
+
type: :runtime
|
|
89
|
+
prerelease: false
|
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
91
|
+
requirements:
|
|
92
|
+
- - "~>"
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: '2.3'
|
|
81
95
|
- !ruby/object:Gem::Dependency
|
|
82
96
|
name: aws-sdk-ec2
|
|
83
97
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -254,8 +268,12 @@ files:
|
|
|
254
268
|
- lib/cfnvpn/globals.rb
|
|
255
269
|
- lib/cfnvpn/log.rb
|
|
256
270
|
- lib/cfnvpn/s3.rb
|
|
271
|
+
- lib/cfnvpn/s3_bucket.rb
|
|
257
272
|
- lib/cfnvpn/string.rb
|
|
258
273
|
- lib/cfnvpn/templates/helper.rb
|
|
274
|
+
- lib/cfnvpn/templates/lambdas.rb
|
|
275
|
+
- lib/cfnvpn/templates/lambdas/auto_route_populator/app.py
|
|
276
|
+
- lib/cfnvpn/templates/lambdas/scheduler/app.py
|
|
259
277
|
- lib/cfnvpn/templates/vpn.rb
|
|
260
278
|
- lib/cfnvpn/version.rb
|
|
261
279
|
homepage: https://github.com/base2services/aws-client-vpn
|
|
@@ -279,7 +297,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
279
297
|
- !ruby/object:Gem::Version
|
|
280
298
|
version: '0'
|
|
281
299
|
requirements: []
|
|
282
|
-
rubygems_version: 3.1.
|
|
300
|
+
rubygems_version: 3.1.6
|
|
283
301
|
signing_key:
|
|
284
302
|
specification_version: 4
|
|
285
303
|
summary: creates and manages resources for the aws client vpn
|