Skip to content

Commit

Permalink
handle variables recursively, add some examples
Browse files Browse the repository at this point in the history
  • Loading branch information
Larry Hitchon committed Apr 14, 2018
1 parent 78cd3ee commit bbf9a06
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 3 deletions.
32 changes: 32 additions & 0 deletions example-files/config/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
variable "instance_type" {
default = "t2.micro"
}

variable "ami" {
default = "ami-f2d3638a"
}

variable "project" {
default = "demo"
}

resource "aws_instance" "first" {
ami = "${var.ami}"
instance_type = "${var.instance_type}"
tags = {
project = "${var.project}"
}
}

variable "instance_type_2" {
default = "c4.large"
}

resource "aws_instance" "second" {
ami = "${var.ami}"
instance_type = "${var.instance_type_2}"
tags = {
project = "${var.project}"
}
}

24 changes: 24 additions & 0 deletions example-files/rules/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
version: 1
description: Rules for Terraform configuration files
type: Terraform
files:
- "*.tf"
rules:

- id: INSTANCE_TYPE
message: Instance type should be t2.micro or m3.medium
resource: aws_instance
assertions:
- key: instance_type
op: in
value: t2.micro,m3.medium
severity: WARNING

- id: PROJECT_TAG
message: Check project tag
resource: aws_instance
assertions:
- key: "tags[].project|[0]"
op: eq
value: demo
severity: WARNING
31 changes: 28 additions & 3 deletions linter/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,40 @@ func (l TerraformResourceLoader) Load(filename string) ([]assertion.Resource, er
return resources, nil
}

func replaceVariables(templateResource map[string]interface{}, variables map[string]interface{}) map[string]interface{} {
func replaceVariables(templateResource interface{}, variables map[string]interface{}) interface{} {
switch v := templateResource.(type) {
case map[string]interface{}:
return replaceVariablesInMap(v, variables)
default:
assertion.Debugf("replaceVariables cannot process type %T\n", v)
return templateResource
}
}

func replaceVariablesInMap(templateResource map[string]interface{}, variables map[string]interface{}) interface{} {
for key, value := range templateResource {
if s, ok := value.(string); ok { // FIXME is not a string, need to recurse
templateResource[key] = resolveValue(s, variables)
switch v := value.(type) {
case string:
templateResource[key] = resolveValue(v, variables)
case map[string]interface{}:
templateResource[key] = replaceVariablesInMap(v, variables)
case []interface{}:
templateResource[key] = replaceVariablesInList(v, variables)
default:
assertion.Debugf("replaceVariablesInMap cannot process type %T\n", v)
}
}
return templateResource
}

func replaceVariablesInList(list []interface{}, variables map[string]interface{}) []interface{} {
result := []interface{}{}
for _, e := range list {
result = append(result, replaceVariables(e, variables))
}
return result
}

func resolveValue(s string, variables map[string]interface{}) string {
pattern := "[$][{]var[.](?P<name>.*)[}]"
re, _ := regexp.Compile(pattern)
Expand Down

0 comments on commit bbf9a06

Please sign in to comment.