@@ -12,19 +12,21 @@ import { LldConfigBase } from '../types/lldConfig.js';
12
12
13
13
export const execAsync = promisify ( exec ) ;
14
14
15
- interface TerraformState {
16
- resources : Array < {
17
- type : string ;
18
- name : string ;
19
- values : {
20
- function_name ?: string ;
21
- handler ?: string ;
22
- source_dir ?: string ;
23
- source_file ?: string ;
15
+ interface TerraformResource {
16
+ type : string ;
17
+ name : string ;
18
+ address : string ;
19
+ values : {
20
+ function_name ?: string ;
21
+ handler ?: string ;
22
+ source_dir ?: string ;
23
+ source_file ?: string ;
24
+ query ?: {
25
+ source_path ?: string ;
24
26
} ;
25
- //dependencies > depends_on
26
- depends_on : Array < string > ;
27
- } > ;
27
+ } ;
28
+ //dependencies > depends_on
29
+ depends_on : Array < string > ;
28
30
}
29
31
30
32
/**
@@ -151,15 +153,15 @@ export class TerraformFramework implements IFramework {
151
153
return lambdasDiscovered ;
152
154
}
153
155
154
- protected extractLambdaInfo ( state : TerraformState ) {
156
+ protected extractLambdaInfo ( resources : TerraformResource [ ] ) {
155
157
const lambdas : Array < {
156
158
functionName : string ;
157
159
sourceDir ?: string ;
158
160
sourceFilename ?: string ;
159
161
handler : string ;
160
162
} > = [ ] ;
161
163
162
- for ( const resource of state . resources ) {
164
+ for ( const resource of resources ) {
163
165
if ( resource . type === 'aws_lambda_function' ) {
164
166
Logger . verbose (
165
167
'[Terraform] Found Lambda:' ,
@@ -186,9 +188,7 @@ export class TerraformFramework implements IFramework {
186
188
if ( archiveFileResourceName ) {
187
189
// get the resource
188
190
const name = archiveFileResourceName . split ( '.' ) [ 2 ] ;
189
- const archiveFileResource = state . resources . find (
190
- ( r ) => r . name === name ,
191
- ) ;
191
+ const archiveFileResource = resources . find ( ( r ) => r . name === name ) ;
192
192
193
193
// get source_dir or source_filename
194
194
if ( archiveFileResource ) {
@@ -197,6 +197,28 @@ export class TerraformFramework implements IFramework {
197
197
}
198
198
}
199
199
200
+ // get dependency "archive_prepare" = serverless.tf support
201
+ const archivePrepareResourceName = dependencies . find ( ( dep ) =>
202
+ dep . includes ( '.archive_prepare' ) ,
203
+ ) ;
204
+
205
+ if ( archivePrepareResourceName ) {
206
+ // get the resource
207
+ const name = archivePrepareResourceName ;
208
+ const archivePrepareResource = resources . find ( ( r ) =>
209
+ r . address ?. startsWith ( name ) ,
210
+ ) ;
211
+
212
+ // get source_dir or source_filename
213
+ if ( archivePrepareResource ) {
214
+ sourceDir =
215
+ archivePrepareResource . values . query ?. source_path ?. replaceAll (
216
+ '"' ,
217
+ '' ,
218
+ ) ;
219
+ }
220
+ }
221
+
200
222
if ( ! sourceDir && ! sourceFilename ) {
201
223
Logger . error ( `Failed to find source code for Lambda ${ functionName } ` ) ;
202
224
} else {
@@ -213,7 +235,7 @@ export class TerraformFramework implements IFramework {
213
235
return lambdas ;
214
236
}
215
237
216
- protected async readTerraformState ( ) : Promise < TerraformState > {
238
+ protected async readTerraformState ( ) : Promise < TerraformResource [ ] > {
217
239
// Is there a better way to get the Terraform state???
218
240
219
241
let output : any ;
@@ -254,7 +276,16 @@ export class TerraformFramework implements IFramework {
254
276
255
277
try {
256
278
const state = JSON . parse ( jsonString ) ;
257
- return state . values . root_module as TerraformState ;
279
+
280
+ const rootResources : TerraformResource [ ] =
281
+ state . values ?. root_module ?. resources ?? [ ] ;
282
+
283
+ const childResources : TerraformResource [ ] =
284
+ state . values ?. root_module ?. child_modules
285
+ ?. map ( ( m : any ) => m . resources )
286
+ . flat ( ) ?? [ ] ;
287
+
288
+ return [ ...rootResources , ...childResources ] as TerraformResource [ ] ;
258
289
} catch ( error : any ) {
259
290
//save state to file
260
291
await fs . writeFile ( 'terraform-state.json' , jsonString ) ;
0 commit comments