@@ -41,19 +41,19 @@ export class DdbExportStepFunction extends Construct {
41
41
actions : [ 'dynamodb:ExportTableToPointInTime' ] ,
42
42
resources : [ props . table . tableArn ] ,
43
43
} )
44
- ) ;
44
+ )
45
45
lambdaStartExport . addToRolePolicy (
46
46
new iam . PolicyStatement ( {
47
47
actions : [ 's3:PutObject' ] ,
48
48
resources : [ `${ props . bucket . bucketArn } /*` ] ,
49
49
} )
50
- ) ;
50
+ )
51
51
lambdaStartExport . addToRolePolicy (
52
52
new iam . PolicyStatement ( {
53
53
actions : [ 'kms:Decrypt' ] ,
54
54
resources : [ props . bucket . encryptionKey ! . keyArn ] ,
55
55
} )
56
- ) ;
56
+ )
57
57
58
58
const lambdaCheckExportState = new lambdaNodejs . NodejsFunction ( this , 'lambda-function-check-export-state' , {
59
59
functionName : `${ props . name } -ddb-check-export-state` ,
@@ -87,15 +87,136 @@ export class DdbExportStepFunction extends Construct {
87
87
errors : [ 'InProgressError' ] ,
88
88
} )
89
89
90
- const athenaDropTable = new stepfunctions_tasks . AthenaStartQueryExecution ( this , 'drop table' , {
91
- queryString : `DROP TABLE IF EXISTS \`${ props . glueDb . databaseName } .ddb_exported_table\`;` ,
90
+ const athenaTableName = 'ddb_exported_table'
91
+
92
+ const athenaDropTable = new stepfunctions_tasks . AthenaStartQueryExecution ( this , 'drop Athena table' , {
93
+ queryString : `DROP TABLE IF EXISTS \`${ props . glueDb . databaseName } .${ athenaTableName } \`;` ,
92
94
workGroup : props . athenaWorkgroup . name ,
93
- } ) ;
95
+ queryExecutionContext : {
96
+ databaseName : props . glueDb . databaseName ,
97
+ } ,
98
+ integrationPattern : stepfunctions . IntegrationPattern . RUN_JOB ,
99
+ resultPath : '$.TaskResult' ,
100
+ } )
101
+
102
+ const getSqlString = ( file : string ) : string => {
103
+ let createTableCommand = readFileSync ( join ( __dirname , `${ file } ` ) , 'utf-8' ) . toString ( )
104
+ const s3Location = `s3://${ props . bucket . bucketName } /ddb-exports/AWSDynamoDB/ddb-export-id/data/`
105
+ createTableCommand = createTableCommand . replace ( / s 3 L o c a t i o n / g, s3Location )
106
+ createTableCommand = createTableCommand . replace ( / t a b l e _ n a m e / g, athenaTableName )
107
+ return createTableCommand
108
+ }
109
+
110
+ const queryStringCreateTable = getSqlString ( 'createTable.sql' )
94
111
95
- const athenaCreateTable = new stepfunctions . Pass ( this , 'create table' , { } ) ;
96
- const sfnTaskCreateSelectQuery = new stepfunctions . Pass ( this , 'create SELECT query' , { } ) ;
112
+ // const athenaCreateTable = new stepfunctions_tasks.AthenaStartQueryExecution (this, 'create table', {
113
+ // queryString: queryStringCreateTable,
97
114
98
- const definition = sfnTaskStartExport . next ( sfnTaskCheckExportState ) . next ( athenaDropTable ) . next ( athenaCreateTable ) . next ( sfnTaskCreateSelectQuery ) ;
115
+ // workGroup: props.athenaWorkgroup.name,
116
+ // queryExecutionContext: {
117
+ // databaseName: props.glueDb.databaseName,
118
+ // },
119
+ // resultPath: '$.TaskResult',
120
+ // })
121
+
122
+ const lambdaCreateAthenaTable = new lambdaNodejs . NodejsFunction ( this , 'lambda-function-create-athena-table' , {
123
+ functionName : `${ props . name } -create-athena-table` ,
124
+ timeout : Duration . minutes ( 2 ) ,
125
+ environment : {
126
+ REGION : Stack . of ( this ) . region ,
127
+ GLUE_DATABASE_NAME : props . glueDb . databaseName ,
128
+ ATHENA_WORKGROUP_NAME : props . athenaWorkgroup . name ,
129
+ ATHENA_QUERY_STRING_CREATE_TABLE : queryStringCreateTable ,
130
+ } ,
131
+ } )
132
+ lambdaCreateAthenaTable . addToRolePolicy (
133
+ new iam . PolicyStatement ( {
134
+ actions : [ 'athena:StartQueryExecution' ] ,
135
+ resources : [ `arn:aws:athena:${ Stack . of ( this ) . region } :${ Stack . of ( this ) . account } :workgroup/${ props . athenaWorkgroup . name } ` ] ,
136
+ } )
137
+ )
138
+ lambdaCreateAthenaTable . addToRolePolicy (
139
+ new iam . PolicyStatement ( {
140
+ actions : [ 's3:*' ] ,
141
+ resources : [ `*` ] ,
142
+ // actions: ['s3:PutObject'],
143
+ // resources: [`${props.bucket.bucketArn}/*`],
144
+ } )
145
+ ) ;
146
+ lambdaCreateAthenaTable . addToRolePolicy (
147
+ new iam . PolicyStatement ( {
148
+ actions : [ 'kms:*' ] ,
149
+ resources : [ '*' ] ,
150
+ // actions: ['kms:Decrypt'],
151
+ // resources: [props.bucket.encryptionKey!.keyArn],
152
+ } )
153
+ ) ;
154
+ lambdaCreateAthenaTable . addToRolePolicy (
155
+ new iam . PolicyStatement ( {
156
+ actions : [
157
+ 'glue:BatchCreatePartition' ,
158
+ 'glue:BatchDeletePartition' ,
159
+ 'glue:BatchDeleteTable' ,
160
+ 'glue:BatchGetPartition' ,
161
+ 'glue:CreateDatabase' ,
162
+ 'glue:CreatePartition' ,
163
+ 'glue:CreateTable' ,
164
+ 'glue:DeleteDatabase' ,
165
+ 'glue:DeletePartition' ,
166
+ 'glue:DeleteTable' ,
167
+ 'glue:GetDatabase' ,
168
+ 'glue:GetDatabases' ,
169
+ 'glue:GetPartition' ,
170
+ 'glue:GetPartitions' ,
171
+ 'glue:GetTable' ,
172
+ 'glue:GetTables' ,
173
+ 'glue:UpdateDatabase' ,
174
+ 'glue:UpdatePartition' ,
175
+ 'glue:UpdateTable'
176
+ ] ,
177
+ resources : [
178
+ `arn:aws:glue:${ Stack . of ( this ) . region } :${ Stack . of ( this ) . account } :catalog` , // remove?
179
+ `arn:aws:glue:${ Stack . of ( this ) . region } :${ Stack . of ( this ) . account } :database/default` , // remove?
180
+ props . glueDb . databaseArn ,
181
+ `arn:aws:glue:${ Stack . of ( this ) . region } :${ Stack . of ( this ) . account } :table/${ props . glueDb . databaseName } /${ athenaTableName } ` ] ,
182
+ } )
183
+ ) ;
184
+
185
+ const sfnTaskCreateAthenaTable = new stepfunctions_tasks . LambdaInvoke ( this , 'create Athena table' , {
186
+ lambdaFunction : lambdaCreateAthenaTable ,
187
+ } )
188
+
189
+ const queryStringReadTable = getSqlString ( 'readTable.sql' )
190
+
191
+ const lambdaCreateAthenaQuery = new lambdaNodejs . NodejsFunction ( this , 'lambda-function-create-athena-query' , {
192
+ functionName : `${ props . name } -create-athena-query` ,
193
+ timeout : Duration . minutes ( 2 ) ,
194
+ environment : {
195
+ REGION : Stack . of ( this ) . region ,
196
+ ATHENA_WORKGROUP_NAME : props . athenaWorkgroup . name ,
197
+ ATHENA_TABLE_NAME : athenaTableName ,
198
+ GLUE_DATABASE_NAME : props . glueDb . databaseName ,
199
+ ATHENA_QUERY_STRING_READ_TABLE : queryStringReadTable ,
200
+ } ,
201
+ } )
202
+ lambdaCreateAthenaQuery . addToRolePolicy (
203
+ new iam . PolicyStatement ( {
204
+ actions : [ 'athena:CreateNamedQuery' , 'athena:ListNamedQueries' , 'athena:GetNamedQuery' , 'athena:UpdateNamedQuery' ] ,
205
+ resources : [ `arn:aws:athena:${ Stack . of ( this ) . region } :${ Stack . of ( this ) . account } :workgroup/${ props . athenaWorkgroup . name } ` ] ,
206
+ } )
207
+ )
208
+ lambdaCreateAthenaQuery . addToRolePolicy (
209
+ new iam . PolicyStatement ( {
210
+ actions : [ 'kms:Decrypt' , 'kms:GenerateDataKey' ] ,
211
+ resources : [ props . athenaResultBucket . encryptionKey ! . keyArn ] ,
212
+ } )
213
+ )
214
+
215
+ const sfnTaskCreateAthenaQuery = new stepfunctions_tasks . LambdaInvoke ( this , 'create Athena query' , {
216
+ lambdaFunction : lambdaCreateAthenaQuery ,
217
+ } )
218
+
219
+ const definition = sfnTaskStartExport . next ( sfnTaskCheckExportState ) . next ( athenaDropTable ) . next ( sfnTaskCreateAthenaTable ) . next ( sfnTaskCreateAthenaQuery )
99
220
100
221
const sfn = new stepfunctions . StateMachine ( this , 'ddb-export-state-machine' , {
101
222
stateMachineName : `${ props . name } -ddb-export-state-machine` ,
@@ -105,17 +226,40 @@ export class DdbExportStepFunction extends Construct {
105
226
sfn . addToRolePolicy (
106
227
new iam . PolicyStatement ( {
107
228
actions : [ 's3:*' ] ,
108
- resources : [ props . athenaResultBucket . bucketArn ,
109
- `${ props . athenaResultBucket . bucketArn } /*` ] ,
229
+ resources : [ props . athenaResultBucket . bucketArn , `${ props . athenaResultBucket . bucketArn } /*` ] ,
110
230
} )
111
- ) ;
231
+ )
112
232
sfn . addToRolePolicy (
113
233
new iam . PolicyStatement ( {
114
- actions : [ 'kms:Decrypt' ] ,
234
+ actions : [ 'kms:Decrypt' , 'kms:GenerateDataKey' ] ,
115
235
resources : [ props . athenaResultBucket . encryptionKey ! . keyArn ] ,
116
236
} )
117
- ) ;
118
-
119
-
237
+ )
238
+ // sfn.addToRolePolicy(
239
+ // new iam.PolicyStatement({
240
+ // actions: [
241
+ // 'glue:BatchCreatePartition',
242
+ // 'glue:BatchDeletePartition',
243
+ // 'glue:BatchDeleteTable',
244
+ // 'glue:BatchGetPartition',
245
+ // 'glue:CreateDatabase',
246
+ // 'glue:CreatePartition',
247
+ // 'glue:CreateTable',
248
+ // 'glue:DeleteDatabase',
249
+ // 'glue:DeletePartition',
250
+ // 'glue:DeleteTable',
251
+ // 'glue:GetDatabase',
252
+ // 'glue:GetDatabases',
253
+ // 'glue:GetPartition',
254
+ // 'glue:GetPartitions',
255
+ // 'glue:GetTable',
256
+ // 'glue:GetTables',
257
+ // 'glue:UpdateDatabase',
258
+ // 'glue:UpdatePartition',
259
+ // 'glue:UpdateTable'
260
+ // ],
261
+ // resources: [props.glueDb.databaseArn, `arn:aws:glue:${Stack.of(this).region}:${Stack.of(this).account}:table/${props.glueDb.databaseName}/${athenaTableName}`],
262
+ // })
263
+ // )
120
264
}
121
265
}
0 commit comments