Skip to content

Commit

Permalink
parse and auto detect TF module dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
pulasthibandara committed Aug 11, 2024
1 parent 96e391d commit 6cd3739
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 1 deletion.
5 changes: 4 additions & 1 deletion packages/terraform/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@
"license": "MIT",
"main": "src/index.js",
"builders": "./executors.json",
"generators": "./generators.json"
"generators": "./generators.json",
"dependencies": {
"@evops/hcl-terraform-parser": "^1.0.0"
}
}
66 changes: 66 additions & 0 deletions packages/terraform/src/graph.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import * as hclParser from '@evops/hcl-terraform-parser'
import {
CreateDependencies,
RawProjectGraphDependency,
workspaceRoot
} from '@nx/devkit'
import * as fs from 'node:fs/promises'
import * as path from 'node:path'
import { DependencyType } from 'nx/src/config/project-graph'

const isLocalPath = (path: string) => {
return path.startsWith('./') || path.startsWith('../')
}

export const createDependencies: CreateDependencies = async (_, ctx) => {
const results: RawProjectGraphDependency[] = []

const projectRootsToProject: [projectRoot: string, name: string][] =
Object.entries(ctx.projects).map(([name, project]) => [project.root, name])

for (const project of Object.keys(ctx.projects)) {
// find tf files to process in the project
const tfFilesToProcess =
ctx.filesToProcess.projectFileMap[project]?.filter((file) =>
file.file.endsWith('.tf')
) ?? []

for (const file of tfFilesToProcess) {
const data = await fs.readFile(file.file)
const hclFile = hclParser.parse(data)
const moduleCalls = hclFile['module_calls']

for (const moduleCall of Object.values(moduleCalls)) {
const depSourcePathRel = moduleCall.source

if (!isLocalPath(depSourcePathRel)) {
continue
}

const depSourceAbs = path.resolve(file.file, depSourcePathRel)

const depSourceRelativeToWorkspace = path.relative(
workspaceRoot,
depSourceAbs
)

const targetProject = projectRootsToProject.find(([root]) =>
depSourceRelativeToWorkspace.startsWith(root)
)?.[1]

if (!targetProject || targetProject === project) {
continue
}

results.push({
type: DependencyType.static,
source: project,
target: targetProject,
sourceFile: file.file
})
}
}
}

return results
}
11 changes: 11 additions & 0 deletions packages/terraform/src/hcl-terraform-parser.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
declare module '@evops/hcl-terraform-parser' {
export type HclDef = {
module_calls: {
[key: string]: {
source: string
}
}
}

export function parse(data: Buffer): HclDef
}
1 change: 1 addition & 0 deletions packages/terraform/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './graph'
9 changes: 9 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5692,6 +5692,13 @@ __metadata:
languageName: node
linkType: hard

"@evops/hcl-terraform-parser@npm:^1.0.0":
version: 1.0.0
resolution: "@evops/hcl-terraform-parser@npm:1.0.0"
checksum: 10/d48b92b594a04a10a513e9e2984ac48437348ff23ff0e898e6fdb612715bb0a20c66d176b57f2b828c7c8da1cd282763aed152bcf17c00f67ae2c061c78212fd
languageName: node
linkType: hard

"@fastify/busboy@npm:^2.0.0":
version: 2.1.1
resolution: "@fastify/busboy@npm:2.1.1"
Expand Down Expand Up @@ -7345,6 +7352,8 @@ __metadata:
"@nx-extend/terraform@workspace:packages/terraform":
version: 0.0.0-use.local
resolution: "@nx-extend/terraform@workspace:packages/terraform"
dependencies:
"@evops/hcl-terraform-parser": "npm:^1.0.0"
languageName: unknown
linkType: soft

Expand Down

0 comments on commit 6cd3739

Please sign in to comment.