Skip to content

Commit

Permalink
Handling unresolvable references (#446)
Browse files Browse the repository at this point in the history
* partial fix

* tests and Changelog
  • Loading branch information
Kudbettin authored Jan 15, 2021
1 parent 5534c58 commit 336c000
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# CHANGELOG

## Unreleased
* Fixed an issue where ambigious references were breaking during parsing. ([#446](https://github.com/terraform-compliance/cli/pull/446))

## 1.3.9 (2020-01-10)
* Fixed an issue where incorrect `ref_type` format were breaking during parsing. ([#444](https://github.com/eerkunt/terraform-compliance/pull/444))
* Fixed an issue where \x08 character was breaking JUnit XML conversion during provider version_constraint checks. ([#432](https://github.com/eerkunt/terraform-compliance/pull/432))
Expand Down
43 changes: 42 additions & 1 deletion terraform_compliance/extensions/terraform.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from terraform_compliance.common.helper import seek_key_in_dict, flatten_list, Match, merge_dicts, remove_constant_values
import sys
from copy import deepcopy
from radish.utils import console_write
from terraform_compliance.common.defaults import Defaults
from terraform_compliance.extensions.cache import Cache
from terraform_compliance.common.exceptions import TerraformComplianceInternalFailure
Expand Down Expand Up @@ -357,7 +358,47 @@ def _mount_references(self):
valid_references = [r for r in ref['references'] if not r.startswith(invalid_references)]

for ref in valid_references:
if key not in ref_list:
# if ref is not in the correct format, handle it
if len(ref.split('.')) < 3 and ref.startswith('module'):

# Using for_each and modules together may introduce an issue where the plan.out.json won't include the necessary third part of the reference
# It is partially resolved by mounting the reference to all instances belonging to the module
if 'for_each_expression' in self.configuration['resources'][resource]:

# extract source resources
assumed_source_resources = [k for k in self.resources.keys() if k.startswith(resource)]
# extract for_each keys
assumed_for_each_keys = [k[len(resource):].split('.')[0] for k in assumed_source_resources]
# combine ref with for each keys
assumed_refs = ['{}{}'.format(ref, key) for key in assumed_for_each_keys]
# get all the resources that start with updated ref
ambigious_references = []
for r in self.resources.keys():
for assumed_ref in assumed_refs:
if r.startswith(assumed_ref):
if key in ref_list:
ref_list[key].append(r)
else:
ref_list[key] = [r]

ambigious_references.append(r)

# throw a warning
defaults = Defaults()
console_write('{} {}: {}'.format(defaults.warning_icon,
defaults.warning_colour('WARNING (Mounting)'),
defaults.info_colour('The reference "{}" in resource {} is ambigious.'
' It will be mounted to the following resources:').format(ref, resource)))
for i, r in enumerate(ambigious_references, 1):
console_write(defaults.info_colour('{}. {}'.format(i, r)))

# if the reference can not be resolved, warn the user and continue.
else:
console_write('{} {}: {}'.format(Defaults().warning_icon,
Defaults().warning_colour('WARNING (Mounting)'),
Defaults().info_colour('The reference "{}" in resource {} is ambigious. It will not be mounted.'.format(ref, resource))))
continue
elif key not in ref_list:
ref_list[key] = self._find_resource_from_name(ref)
else:
ref_list[key].extend(self._find_resource_from_name(ref))
Expand Down
28 changes: 28 additions & 0 deletions tests/functional/test_issue-424/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module "ecr_repository" {
source = "./modules/ecr_module"
for_each = var.ecr_repositories

name = each.key
scan_on_push = each.value.scan_on_push
}


resource "aws_iam_role" "test_iam_role" {
for_each = var.ecr_repositories
name = module.ecr_repository[each.key].ecr_name
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
51 changes: 51 additions & 0 deletions tests/functional/test_issue-424/modules/ecr_module/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
variable "name" {
type = string
}

variable "scan_on_push" {
type = string
default = true
}

resource "aws_ecr_repository" "ecr_repository" {
name = var.name
image_tag_mutability = "IMMUTABLE"

image_scanning_configuration {
scan_on_push = var.scan_on_push
}

}

data "aws_ami" "ubuntu" {
most_recent = true

filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}

filter {
name = "virtualization-type"
values = ["hvm"]
}

owners = ["099720109477"] # Canonical
}

resource "aws_instance" "ecr_repository" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"

tags = {
Name = "HelloWorld"
}
}

output "ecr_name" {
value = aws_ecr_repository.ecr_repository.id
}

output "not_ecr_name" {
value = 1234
}
Loading

0 comments on commit 336c000

Please sign in to comment.