-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtemplate.yml
386 lines (386 loc) · 11.9 KB
/
template.yml
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
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
---
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: A basic template for creating a Lambda-backed API Gateway for use as
a custom identity provider in AWS Transfer. It authenticates against an
entry in AWS Secrets Manager of the format server-id/username. Additionaly, the secret
must hold the key-value pairs for all user properties returned to AWS Transfer.
If you choose to also launch the AWS Transfer endpoint it will be provisioned with the SFTP protocol.
This can be changed after launch. Note that FTP is only supported on VPC endpoints
You can modify the Lambda function code to do something different after deployment.
Parameters:
CreateServer:
AllowedValues:
- 'true'
- 'false'
Type: String
Description: Whether this stack creates an AWS Transfer endpoint or not. If the endpoint is created as
part of the stack, the custom identity provider is automatically associated with it.
Default: 'true'
SecretsManagerRegion:
Type: String
Description: (Optional) The region the secrets are stored in. If this value is not provided, the
region this stack is deployed in will be used. Use this field if you are deploying this stack in
a region where SecretsMangager is not available.
Default: ''
TransferEndpointType:
AllowedValues:
- 'PUBLIC'
- 'VPC'
Type: String
Default: 'PUBLIC'
Description: Select PUBLIC if you want a public facing AWS Transfer endpoint or VPC if you want a VPC
based endpoint. Note that only SFTP and FTPS are supported on public endpoints.
TransferSubnetIDs:
Type: String
Default: ''
Description: Required if launching a VPC endpoint. Comma-seperated list of subnets that you would like
the AWS Transfer endpoint to be provisioned into.
TransferVPCID:
Type: String
Default: ''
Description: Required if launching a VPC endpoint. The VPC ID that you would like the AWS Transfer endpoint
to be provisioned into.
Conditions:
CreateServer:
Fn::Equals:
- Ref: CreateServer
- 'true'
NotCreateServer:
Fn::Not:
- Condition: CreateServer
SecretsManagerRegionProvided:
Fn::Not:
- Fn::Equals:
- Ref: SecretsManagerRegion
- ''
TransferVPCEndpoint:
Fn::Equals:
- Ref: TransferEndpointType
- 'VPC'
Outputs:
ServerId:
Value:
Fn::GetAtt: TransferServer.ServerId
Condition: CreateServer
StackArn:
Value:
Ref: AWS::StackId
TransferIdentityProviderUrl:
Description: URL to pass to AWS Transfer CreateServer call as part of optional IdentityProviderDetails
Value:
Fn::Join:
- ''
- - https://
- Ref: CustomIdentityProviderApi
- .execute-api.
- Ref: AWS::Region
- .amazonaws.com/
- Ref: ApiStage
Condition: NotCreateServer
TransferIdentityProviderInvocationRole:
Description: IAM Role to pass to AWS Transfer CreateServer call as part of optional IdentityProviderDetails
Value:
Fn::GetAtt: TransferIdentityProviderRole.Arn
Condition: NotCreateServer
Resources:
TransferServer:
Type: AWS::Transfer::Server
Condition: CreateServer
Properties:
EndpointType:
Ref: TransferEndpointType
EndpointDetails:
Fn::If:
- TransferVPCEndpoint
- SubnetIds:
Fn::Split: [',', Ref: TransferSubnetIDs]
VpcId:
Ref: TransferVPCID
- Ref: AWS::NoValue
IdentityProviderDetails:
InvocationRole:
Fn::GetAtt: TransferIdentityProviderRole.Arn
Url:
Fn::Join:
- ''
- - https://
- Ref: CustomIdentityProviderApi
- .execute-api.
- Ref: AWS::Region
- .amazonaws.com/
- Ref: ApiStage
IdentityProviderType: API_GATEWAY
LoggingRole:
Fn::GetAtt: TransferCWLoggingRole.Arn
TransferCWLoggingRole:
Description: IAM role used by Transfer to log API requests to CloudWatch
Type: AWS::IAM::Role
Condition: CreateServer
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- transfer.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- Fn::Sub: arn:${AWS::Partition}:iam::aws:policy/service-role/AWSTransferLoggingAccess
CustomIdentityProviderApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: Transfer Family Secrets Manager Integration API
Description: API used for Transfer Family to access user information in Secrets Manager
FailOnWarnings: true
EndpointConfiguration:
Types:
- REGIONAL
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- Fn::Sub: arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: LambdaSecretsPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource:
Fn::Sub:
- arn:${AWS::Partition}:secretsmanager:${SecretsRegion}:${AWS::AccountId}:secret:s-*
- SecretsRegion:
Fn::If:
- SecretsManagerRegionProvided
- Ref: SecretsManagerRegion
- Ref: AWS::Region
ApiCloudWatchLogsRole:
Description: IAM role used by API Gateway to log API requests to CloudWatch
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- apigateway.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: ApiGatewayLogsPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:DescribeLogGroups
- logs:DescribeLogStreams
- logs:PutLogEvents
- logs:GetLogEvents
- logs:FilterLogEvents
Resource: "*"
ApiLoggingAccount:
Type: AWS::ApiGateway::Account
DependsOn:
- CustomIdentityProviderApi
Properties:
CloudWatchRoleArn:
Fn::GetAtt: ApiCloudWatchLogsRole.Arn
ApiStage:
Type: AWS::ApiGateway::Stage
Properties:
DeploymentId:
Ref: ApiDeployment202008
MethodSettings:
- DataTraceEnabled: false
HttpMethod: "*"
LoggingLevel: INFO
ResourcePath: "/*"
RestApiId:
Ref: CustomIdentityProviderApi
StageName: prod
ApiDeployment202008:
DependsOn:
- GetUserConfigRequest
Type: AWS::ApiGateway::Deployment
Properties:
RestApiId:
Ref: CustomIdentityProviderApi
TransferIdentityProviderRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: transfer.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: TransferCanInvokeThisApi
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- execute-api:Invoke
Resource:
Fn::Sub: arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${CustomIdentityProviderApi}/prod/GET/*
- PolicyName: TransferCanReadThisApi
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- apigateway:GET
Resource: "*"
GetUserConfigLambda:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Description: A function to lookup and return user data from AWS Secrets Manager.
Handler: index.lambda_handler
Role:
Fn::GetAtt: LambdaExecutionRole.Arn
Runtime: python3.7
Environment:
Variables:
SecretsManagerRegion:
Fn::If:
- SecretsManagerRegionProvided
- Ref: SecretsManagerRegion
- Ref: AWS::Region
GetUserConfigLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:invokeFunction
FunctionName:
Fn::GetAtt: GetUserConfigLambda.Arn
Principal: apigateway.amazonaws.com
SourceArn:
Fn::Sub: arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${CustomIdentityProviderApi}/*
ServersResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId:
Ref: CustomIdentityProviderApi
ParentId:
Fn::GetAtt:
- CustomIdentityProviderApi
- RootResourceId
PathPart: servers
ServerIdResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId:
Ref: CustomIdentityProviderApi
ParentId:
Ref: ServersResource
PathPart: "{serverId}"
UsersResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId:
Ref: CustomIdentityProviderApi
ParentId:
Ref: ServerIdResource
PathPart: users
UserNameResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId:
Ref: CustomIdentityProviderApi
ParentId:
Ref: UsersResource
PathPart: "{username}"
GetUserConfigResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId:
Ref: CustomIdentityProviderApi
ParentId:
Ref: UserNameResource
PathPart: config
GetUserConfigRequest:
Type: AWS::ApiGateway::Method
DependsOn: GetUserConfigResponseModel
Properties:
AuthorizationType: AWS_IAM
HttpMethod: GET
Integration:
Type: AWS
IntegrationHttpMethod: POST
Uri:
Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":apigateway:"
- Ref: AWS::Region
- ":lambda:path/2015-03-31/functions/"
- Fn::GetAtt:
- GetUserConfigLambda
- Arn
- "/invocations"
IntegrationResponses:
- StatusCode: 200
RequestTemplates:
application/json: |
{
"username": "$util.urlDecode($input.params('username'))",
"password": "$util.escapeJavaScript($input.params('Password')).replaceAll("\\'","'")",
"protocol": "$input.params('protocol')",
"serverId": "$input.params('serverId')",
"sourceIp": "$input.params('sourceIp')"
}
RequestParameters:
method.request.header.Password: false
ResourceId:
Ref: GetUserConfigResource
RestApiId:
Ref: CustomIdentityProviderApi
MethodResponses:
- StatusCode: 200
ResponseModels:
application/json: UserConfigResponseModel
GetUserConfigResponseModel:
Type: AWS::ApiGateway::Model
Properties:
RestApiId:
Ref: CustomIdentityProviderApi
ContentType: application/json
Description: API response for GetUserConfig
Name: UserConfigResponseModel
Schema:
"$schema": http://json-schema.org/draft-04/schema#
title: UserUserConfig
type: object
properties:
HomeDirectory:
type: string
Role:
type: string
Policy:
type: string
PublicKeys:
type: array
items:
type: string