Skip to content

Commit

Permalink
✨ add terraform.plan.variables
Browse files Browse the repository at this point in the history
Signed-off-by: Salim Afiune Maya <[email protected]>
  • Loading branch information
afiune committed Jan 22, 2025
1 parent 35e8551 commit 242727b
Show file tree
Hide file tree
Showing 10 changed files with 252 additions and 4 deletions.
2 changes: 1 addition & 1 deletion providers/terraform/connection/hcl_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestLoadHclBlocks(t *testing.T) {
require.NotNil(t, parser)
tfVars := tf.TfVars()
assert.Equal(t, 2, len(tfVars))
assert.Equal(t, 5, len(parser.Files()))
assert.Equal(t, 6, len(parser.Files()))
}

func TestLoadTfvars(t *testing.T) {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions providers/terraform/connection/testdata/dynamic_block/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
variable "environment" {
type = string
}

locals {
set = {
set1 = {
name = "service.type"
value = "LoadBalancer"
}
set2 = {
name = "replicaCount"
value = "2"
}
set3 = {
name = "ingress.enabled"
value = "true"
}
set4 = {
name = "environment"
value = var.environment
}
}
}
resource "helm_release" "nginx" {
name = "my-nginx"
chart = "nginx"
repository = "https://charts.bitnami.com/bitnami"
version = "13.2.12"
dynamic "set" {
for_each = local.set
content {
name = set.value.name
value = set.value.value
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"format_version":"1.2","terraform_version":"1.8.5","variables":{"environment":{"value":"dev"}},"planned_values":{"root_module":{"resources":[{"address":"helm_release.nginx","mode":"managed","type":"helm_release","name":"nginx","provider_name":"registry.terraform.io/hashicorp/helm","schema_version":1,"values":{"atomic":false,"chart":"nginx","cleanup_on_fail":false,"create_namespace":false,"dependency_update":false,"description":null,"devel":null,"disable_crd_hooks":false,"disable_openapi_validation":false,"disable_webhooks":false,"force_update":false,"keyring":null,"lint":false,"max_history":0,"name":"my-nginx","namespace":"default","pass_credentials":false,"postrender":[],"recreate_pods":false,"render_subchart_notes":true,"replace":false,"repository":"https://charts.bitnami.com/bitnami","repository_ca_file":null,"repository_cert_file":null,"repository_key_file":null,"repository_password":null,"repository_username":null,"reset_values":false,"reuse_values":false,"set":[{"name":"environment","type":"","value":"dev"},{"name":"ingress.enabled","type":"","value":"true"},{"name":"replicaCount","type":"","value":"2"},{"name":"service.type","type":"","value":"LoadBalancer"}],"set_list":[],"set_sensitive":[],"skip_crds":false,"status":"deployed","timeout":300,"upgrade_install":null,"values":null,"verify":false,"version":"13.2.12","wait":true,"wait_for_jobs":false},"sensitive_values":{"metadata":[],"postrender":[],"repository_password":true,"set":[{},{},{},{}],"set_list":[],"set_sensitive":[]}}]}},"resource_changes":[{"address":"helm_release.nginx","mode":"managed","type":"helm_release","name":"nginx","provider_name":"registry.terraform.io/hashicorp/helm","change":{"actions":["create"],"before":null,"after":{"atomic":false,"chart":"nginx","cleanup_on_fail":false,"create_namespace":false,"dependency_update":false,"description":null,"devel":null,"disable_crd_hooks":false,"disable_openapi_validation":false,"disable_webhooks":false,"force_update":false,"keyring":null,"lint":false,"max_history":0,"name":"my-nginx","namespace":"default","pass_credentials":false,"postrender":[],"recreate_pods":false,"render_subchart_notes":true,"replace":false,"repository":"https://charts.bitnami.com/bitnami","repository_ca_file":null,"repository_cert_file":null,"repository_key_file":null,"repository_password":null,"repository_username":null,"reset_values":false,"reuse_values":false,"set":[{"name":"environment","type":"","value":"dev"},{"name":"ingress.enabled","type":"","value":"true"},{"name":"replicaCount","type":"","value":"2"},{"name":"service.type","type":"","value":"LoadBalancer"}],"set_list":[],"set_sensitive":[],"skip_crds":false,"status":"deployed","timeout":300,"upgrade_install":null,"values":null,"verify":false,"version":"13.2.12","wait":true,"wait_for_jobs":false},"after_unknown":{"id":true,"manifest":true,"metadata":true,"postrender":[],"set":[{},{},{},{}],"set_list":[],"set_sensitive":[]},"before_sensitive":false,"after_sensitive":{"metadata":[],"postrender":[],"repository_password":true,"set":[{},{},{},{}],"set_list":[],"set_sensitive":[]}}}],"configuration":{"provider_config":{"helm":{"name":"helm","full_name":"registry.terraform.io/hashicorp/helm"}},"root_module":{"resources":[{"address":"helm_release.nginx","mode":"managed","type":"helm_release","name":"nginx","provider_config_key":"helm","expressions":{"chart":{"constant_value":"nginx"},"name":{"constant_value":"my-nginx"},"repository":{"constant_value":"https://charts.bitnami.com/bitnami"},"version":{"constant_value":"13.2.12"}},"schema_version":1}],"variables":{"environment":{}}}},"timestamp":"2025-01-22T19:13:07Z","applyable":true,"complete":true,"errored":false}
8 changes: 5 additions & 3 deletions providers/terraform/connection/tfplan.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ type Plan struct {
PriorState json.RawMessage `json:"prior_state,omitempty"`
Configuration json.RawMessage `json:"configuration,omitempty"`
PlannedValues plannedStateValues `json:"planned_values,omitempty"`
Variables variables `json:"variables,omitempty"`
Variables Variables `json:"variables,omitempty"`
ResourceChanges []ResourceChange `json:"resource_changes,omitempty"`
ResourceDrift []ResourceChange `json:"resource_drift,omitempty"`
RelevantAttributes []resourceAttr `json:"relevant_attributes,omitempty"`
OutputChanges map[string]change `json:"output_changes,omitempty"`
Applyable bool `json:"applyable,omitempty"`
Errored bool `json:"errored,omitempty"`
}

type plannedStateValues struct {
Expand Down Expand Up @@ -83,9 +85,9 @@ type resource struct {
SensitiveValues json.RawMessage `json:"sensitive_values,omitempty"`
}

type variables map[string]*variable
type Variables map[string]*Variable

type variable struct {
type Variable struct {
Value json.RawMessage `json:"value,omitempty"`
}

Expand Down
14 changes: 14 additions & 0 deletions providers/terraform/connection/tfplan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,17 @@ func TestTfplan(t *testing.T) {
require.NoError(t, err)
assert.NotNil(t, plan)
}

func TestTfWithDynamicBlocksAndVariables(t *testing.T) {
data, err := os.ReadFile("./testdata/dynamic_block/tfplan.json")
require.NoError(t, err)

var plan Plan
err = json.Unmarshal(data, &plan)
require.NoError(t, err)
assert.NotNil(t, plan)
_, ok := plan.Variables["environment"] // this exist in the testdata
assert.True(t, ok)
assert.True(t, plan.Applyable)
assert.False(t, plan.Errored)
}
14 changes: 14 additions & 0 deletions providers/terraform/resources/terraform.lr
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ terraform.plan {
terraformVersion string
// Resource changes
resourceChanges() []terraform.plan.resourceChange
// Variables used to generate the Terraform plan
variables []terraform.plan.variable
// Indicates if the plan is applyable or not

Check warning on line 172 in providers/terraform/resources/terraform.lr

View workflow job for this annotation

GitHub Actions / Run spell check

`Indicates if` matches a line_forbidden.patterns entry: `\bIndicates if\b`. (forbidden-pattern)

Check warning on line 172 in providers/terraform/resources/terraform.lr

View workflow job for this annotation

GitHub Actions / Run spell check

`applyable` is not a recognized word. (unrecognized-spelling)
applyable bool

Check warning on line 173 in providers/terraform/resources/terraform.lr

View workflow job for this annotation

GitHub Actions / Run spell check

`applyable` is not a recognized word. (unrecognized-spelling)
// Indicates if the plan errored or not

Check warning on line 174 in providers/terraform/resources/terraform.lr

View workflow job for this annotation

GitHub Actions / Run spell check

`Indicates if` matches a line_forbidden.patterns entry: `\bIndicates if\b`. (forbidden-pattern)
errored bool
}

// Terraform plan configuration
Expand All @@ -177,6 +183,14 @@ terraform.plan.configuration {
resources() []dict
}

// Terraform plan variable
terraform.plan.variable @defaults("name value") {
// Variable name
name string
// Variable value
value dict
}

// Terraform plan resource change
terraform.plan.resourceChange @defaults("type name") {
// Resource address
Expand Down
112 changes: 112 additions & 0 deletions providers/terraform/resources/terraform.lr.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions providers/terraform/resources/terraform.lr.manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,15 @@ resources:
title: Display all loaded Terraform modules
terraform.plan:
fields:
applyable:
min_mondoo_version: 9.0.0
errored:
min_mondoo_version: 9.0.0
formatVersion: {}
resourceChanges: {}
terraformVersion: {}
variables:
min_mondoo_version: 9.0.0
min_mondoo_version: latest
platform:
name:
Expand Down Expand Up @@ -132,6 +138,14 @@ resources:
platform:
name:
- terraform-plan
terraform.plan.variable:
fields:
name: {}
value: {}
min_mondoo_version: 9.0.0
platform:
name:
- terraform-plan
terraform.settings:
fields:
backend:
Expand Down
33 changes: 33 additions & 0 deletions providers/terraform/resources/tfplan.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ func initTerraformPlan(runtime *plugin.Runtime, args map[string]*llx.RawData) (m

args["formatVersion"] = llx.StringData(plan.FormatVersion)
args["terraformVersion"] = llx.StringData(plan.TerraformVersion)
args["applyable"] = llx.BoolData(plan.Applyable)
args["errored"] = llx.BoolData(plan.Errored)
args["variables"] = llx.ArrayData(
variablesToArrayInterface(runtime, plan.Variables),
types.Resource("terraform.plan.variables"),
)

return args, nil, nil
}
Expand Down Expand Up @@ -153,6 +159,11 @@ func (t *mqlTerraformPlanConfiguration) id() (string, error) {
return "terraform.plan.configuration", nil
}

func (t *mqlTerraformPlanVariable) id() (string, error) {
id := t.Name
return "terraform.plan.variable/name/" + id.Data, nil
}

type PlanConfiguration struct {
ProviderConfig map[string]json.RawMessage `json:"provider_config"`
RootModule struct {
Expand Down Expand Up @@ -223,3 +234,25 @@ func (t *mqlTerraformPlanConfiguration) resources() ([]interface{}, error) {
}
return res, nil
}

func variablesToArrayInterface(runtime *plugin.Runtime, variables connection.Variables) []interface{} {
var list []interface{}
for k, v := range variables {
var value interface{}
err := json.Unmarshal(v.Value, &value)
if err != nil {
continue
}
variable, err := CreateResource(runtime, "terraform.plan.variable", map[string]*llx.RawData{
"name": llx.StringData(k),
"value": llx.AnyData(value),
})
if err != nil {
continue
}

list = append(list, variable)
}

return list
}

0 comments on commit 242727b

Please sign in to comment.