Skip to content

Commit

Permalink
feat: readd templatefile support
Browse files Browse the repository at this point in the history
Changes `isPathInRepo` to use wd directory instead of `RepoPath` which is likely incorrect for
Terragrunt projects.

The `RepoPath` property that is infered from detected projects was returning full project
path for detected projects when the autdetected project was inferred from a config file. A
fix for this will be addressed in a further PR.

To fix the templatefile logic I've opted to use the os working directory instead, as this is more
robust.
  • Loading branch information
hugorut committed Apr 29, 2024
1 parent 54f0bdf commit e8342c7
Show file tree
Hide file tree
Showing 22 changed files with 728 additions and 7 deletions.
40 changes: 40 additions & 0 deletions cmd/infracost/breakdown_test.go
Expand Up @@ -1322,3 +1322,43 @@ func TestBreakdownSkipAutodetectionIfTerraformVarFilePassed(t *testing.T) {
nil,
)
}

func TestBreakdownTerragruntFileFuncs(t *testing.T) {
if os.Getenv("GITHUB_ACTIONS") == "" {
t.Skip("skipping as this test is only designed for GitHub Actions")
}

t.Setenv("INFRACOST_CI_PLATFORM", "github_app")

testName := testutil.CalcGoldenFileTestdataDirName()
dir := path.Join("./testdata", testName)
GoldenFileCommandTest(
t,
testutil.CalcGoldenFileTestdataDirName(),
[]string{
"breakdown",
"--path", dir,
},
&GoldenFileOptions{CaptureLogs: true, IgnoreNonGraph: true},
)
}

func TestBreakdownTerraformFileFuncs(t *testing.T) {
if os.Getenv("GITHUB_ACTIONS") == "" {
t.Skip("skipping as this test is only designed for GitHub Actions")
}

t.Setenv("INFRACOST_CI_PLATFORM", "github_app")

testName := testutil.CalcGoldenFileTestdataDirName()
dir := path.Join("./testdata", testName)
GoldenFileCommandTest(
t,
testutil.CalcGoldenFileTestdataDirName(),
[]string{
"breakdown",
"--path", dir,
},
&GoldenFileOptions{CaptureLogs: true, IgnoreNonGraph: true},
)
}

Large diffs are not rendered by default.

@@ -0,0 +1,3 @@
{
"instance_type": "m5.large"
}
70 changes: 70 additions & 0 deletions cmd/infracost/testdata/breakdown_terraform_file_funcs/main.tf
@@ -0,0 +1,70 @@
provider "aws" {
region = "us-east-1"
skip_credentials_validation = true
skip_requesting_account_id = true
access_key = "mock_access_key"
secret_key = "mock_secret_key"
}

locals {
files = [
{ name = "cd", file = "instance.json", },
{ name = "sym", file = "sym-instance.json", },
{ name = "pd", file = "../../../testdata/instance.json", },
{
name = "abs",
file = "/home/runner/work/infracost/infracost/cmd/infracost/testdata/breakdown_terraform_file_funcs/instance.json",
},
{ name = "pdabs", file = "/home/runner/work/infracost/infracost/cmd/testdata/instance.json", },
]
dirs = [
{ name = "cd", dir = "." },
{ name = "pd", dir = "../../../testdata" },
{ name = "abs", dir = "/home/runner/work/infracost/infracost/cmd/infracost/testdata/breakdown_terraform_file_funcs/" },
{ name = "pdabs", dir = "/home/runner/work/infracost/infracost/cmd/testdata/" },

]
template_files = [
{ name = "cd", file = "templ.tftpl", },
{ name = "pd", file = "../../../testdata/templ.tftpl", },
{
name = "abs", file = "/home/runner/work/infracost/infracost/cmd/infracost/testdata/breakdown_terraform_file_funcs/templ.tftpl",
},
{ name = "pdabs", file = "/home/runner/work/infracost/infracost/cmd/testdata/templ.tftpl", }
]
}

resource "aws_instance" "file" {
for_each = { for f in local.files : f.name => f.file }

ami = "ami-674cbc1e"
instance_type = jsondecode(file(each.value)).instance_type
}

module "mod_files" {
source = "./modules/test"
}

resource "aws_instance" "fileexists" {
for_each = { for f in local.files : f.name => f.file }
ami = "ami-674cbc1e"
instance_type = fileexists(each.value) ? "e" : "ne"
}

resource "aws_instance" "fileset" {
for_each = { for f in local.dirs : f.name => f.dir }
ami = "ami-674cbc1e"
instance_type = length(fileset(each.value, "*.json"))
}

resource "aws_instance" "filemd5" {
for_each = { for f in local.files : f.name => f.file }
ami = "ami-674cbc1e"
instance_type = filemd5(each.value)
}

resource "aws_instance" "template_file" {
for_each = { for f in local.template_files : f.name => f.file }
ami = "ami-674cbc1e"
instance_type = jsondecode(templatefile(each.value, {})).instance_type
}
@@ -0,0 +1,3 @@
{
"instance_type": "m5.2xlarge"
}
@@ -0,0 +1,21 @@
locals {
files = [
{ name = "cd", file = "${path.module}/instance.json", },
{ name = "rootcd", file = "${path.module}/../../instance.json", },
{ name = "pd", file = "${path.module}/../../../../testdata/instance.json", },
]
}

resource "aws_instance" "file" {
for_each = { for f in local.files : f.name => f.file }

ami = "ami-674cbc1e"
instance_type = jsondecode(file(each.value)).instance_type
}

resource "aws_instance" "fileexists" {
for_each = { for f in local.files : f.name => f.file }

ami = "ami-674cbc1e"
instance_type = fileexists(each.value) ? "e" : "ne"
}
@@ -0,0 +1,3 @@
${jsonencode({
"instance_type": "t2.micro",
})}

Large diffs are not rendered by default.

@@ -0,0 +1,3 @@
{
"instance_type": "m5.large"
}
70 changes: 70 additions & 0 deletions cmd/infracost/testdata/breakdown_terragrunt_file_funcs/main.tf
@@ -0,0 +1,70 @@
provider "aws" {
region = "us-east-1"
skip_credentials_validation = true
skip_requesting_account_id = true
access_key = "mock_access_key"
secret_key = "mock_secret_key"
}

locals {
files = [
{ name = "cd", file = "instance.json", },
{ name = "sym", file = "sym-instance.json", },
{ name = "pd", file = "../../../testdata/instance.json", },
{
name = "abs",
file = "/home/runner/work/infracost/infracost/cmd/infracost/testdata/breakdown_terraform_file_funcs/instance.json",
},
{ name = "pdabs", file = "/home/runner/work/infracost/infracost/cmd/testdata/instance.json", },
]
dirs = [
{ name = "cd", dir = "." },
{ name = "pd", dir = "../../../testdata" },
{ name = "abs", dir = "/home/runner/work/infracost/infracost/cmd/infracost/testdata/breakdown_terraform_file_funcs/" },
{ name = "pdabs", dir = "/home/runner/work/infracost/infracost/cmd/testdata/" },

]
template_files = [
{ name = "cd", file = "templ.tftpl", },
{ name = "pd", file = "../../../testdata/templ.tftpl", },
{
name = "abs", file = "/home/runner/work/infracost/infracost/cmd/infracost/testdata/breakdown_terraform_file_funcs/templ.tftpl",
},
{ name = "pdabs", file = "/home/runner/work/infracost/infracost/cmd/testdata/templ.tftpl", }
]
}

resource "aws_instance" "file" {
for_each = { for f in local.files : f.name => f.file }

ami = "ami-674cbc1e"
instance_type = jsondecode(file(each.value)).instance_type
}

module "mod_files" {
source = "./modules/test"
}

resource "aws_instance" "fileexists" {
for_each = { for f in local.files : f.name => f.file }
ami = "ami-674cbc1e"
instance_type = fileexists(each.value) ? "e" : "ne"
}

resource "aws_instance" "fileset" {
for_each = { for f in local.dirs : f.name => f.dir }
ami = "ami-674cbc1e"
instance_type = length(fileset(each.value, "*.json"))
}

resource "aws_instance" "filemd5" {
for_each = { for f in local.files : f.name => f.file }
ami = "ami-674cbc1e"
instance_type = filemd5(each.value)
}

resource "aws_instance" "template_file" {
for_each = { for f in local.template_files : f.name => f.file }
ami = "ami-674cbc1e"
instance_type = jsondecode(templatefile(each.value, {})).instance_type
}
@@ -0,0 +1,3 @@
{
"instance_type": "m5.2xlarge"
}
@@ -0,0 +1,21 @@
locals {
files = [
{ name = "cd", file = "${path.module}/instance.json", },
{ name = "rootcd", file = "${path.module}/../../instance.json", },
{ name = "pd", file = "${path.module}/../../../../testdata/instance.json", },
]
}

resource "aws_instance" "file" {
for_each = { for f in local.files : f.name => f.file }

ami = "ami-674cbc1e"
instance_type = jsondecode(file(each.value)).instance_type
}

resource "aws_instance" "fileexists" {
for_each = { for f in local.files : f.name => f.file }

ami = "ami-674cbc1e"
instance_type = fileexists(each.value) ? "e" : "ne"
}
@@ -0,0 +1,3 @@
${jsonencode({
"instance_type": "t2.micro",
})}
@@ -0,0 +1,5 @@
inputs = {
get_aws_account_id = get_aws_account_id()
get_aws_caller_identity_arn = get_aws_caller_identity_arn()
get_aws_caller_identity_user_id = get_aws_caller_identity_user_id()
}
3 changes: 3 additions & 0 deletions cmd/testdata/instance.json
@@ -0,0 +1,3 @@
{
"instance_type": "m5.8xlarge"
}
3 changes: 3 additions & 0 deletions cmd/testdata/templ.tftpl
@@ -0,0 +1,3 @@
${jsonencode({
"instance_type": "m5.12xlarge",
})}
7 changes: 6 additions & 1 deletion internal/hcl/evaluator.go
Expand Up @@ -1150,7 +1150,7 @@ func (e *Evaluator) loadModules(lastContext hcl.EvalContext) {
// ExpFunctions returns the set of functions that should be used to when evaluating
// expressions in the receiving scope.
func ExpFunctions(baseDir string, logger zerolog.Logger) map[string]function.Function {
return map[string]function.Function{
fns := map[string]function.Function{
"abs": stdlib.AbsoluteFunc,
"abspath": funcs.AbsPathFunc,
"basename": funcs.BasenameFunc,
Expand Down Expand Up @@ -1261,4 +1261,9 @@ func ExpFunctions(baseDir string, logger zerolog.Logger) map[string]function.Fun
"zipmap": stdlib.ZipmapFunc,
}

fns["templatefile"] = funcs.MakeTemplateFileFunc(baseDir, func() map[string]function.Function {
return fns
})

return fns
}

0 comments on commit e8342c7

Please sign in to comment.