Code Monkey home page Code Monkey logo

Comments (2)

jkrauze avatar jkrauze commented on June 18, 2024

The scenario to reproduce the issue

File structure:

% tree terraform
terraform
├── main.tf
├── my-module
│   ├── module.tf
│   ├── my-data-module
│   │   └── output.tf
│   ├── my-nested-module
│   │   └── sg.tf
│   └── sg.tf
└── terraform.tf

test.zip

Lets say our terraform module uses a my-module module

main.tf

module "component" {
  source = "./my-module"
}

the my-module module creates its own security group using the my-data-module as a data source

my-module/sg.tf

module "data-common" {
  source = "./my-data-module"
}

resource "aws_security_group" "example_sg" {
  name        = "example_sg"
  description = "Example security group"

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = module.data-common.cidr_blocks
  }
}

also it uses the my-nested-module to create another security group

my-module/module.tf

module "nested-component" {
  source = "./my-nested-module"
}

my-module/my-nested-module/sg.tf

resource "aws_security_group" "example_sg_nested_host" {
  name        = "example_sg_nested_host"
  description = "Example security group nested"
}

resource "aws_security_group" "example_sg_nested_client" {
  name        = "example_sg_nested_client"
  description = "Example security group nested"
}

resource "aws_security_group_rule" "example_sg_nested_host_ingress_client" {
  source_security_group_id = aws_security_group.example_sg_nested_client.id
  security_group_id        = aws_security_group.example_sg_nested_host.id
  type                     = "ingress"
  from_port                = 443
  to_port                  = 443
  protocol                 = "tcp"
}

resource "aws_security_group_rule" "example_sg_nested_client_egress_host" {
  source_security_group_id = aws_security_group.example_sg_nested_host.id
  security_group_id        = aws_security_group.example_sg_nested_client.id
  type                     = "egress"
  from_port                = 443
  to_port                  = 443
  protocol                 = "tcp"
}

This setup causes the error described in the issue and a following warning

❗ WARNING (mounting): The reference "module.data-common" in resource aws_security_group.example_sg is ambiguous. It will not be mounted.

Observation

If we stop using my-data-module the issue disappears. After replacing the my-module/sg.tf file with a following content

my-module/sg.tf

resource "aws_security_group" "example_sg" {
  name        = "example_sg"
  description = "Example security group"

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

it starts working fine again.

from cli.

jkrauze avatar jkrauze commented on June 18, 2024

By adding a debug log in the if statement here

if parameter not in self.resources[source_resource]['values']:
self.resources[source_resource]['values'][parameter] = target_resource

like this

                    if parameter not in self.resources[source_resource]['values']:
                        self.resources[source_resource]['values'][parameter] = target_resource
                        defaults = Defaults()
                        console_write('{} {}: {}'.format(defaults.warning_icon,
                                    defaults.warning_colour('WARNING (test)'),
                                    defaults.info_colour('Injecting string into "{}" parameter... Source resource {}, target resource {} ref type "{}".'
                                                        ''.format(parameter, source_resource, target_resource, ref_type))))

and another one just before the failing line here

if ref_type not in self.resources[target_resource]['values']:
self.resources[target_resource]['values'][ref_type] = []

like this

                    if ref_type in self.resources[target_resource]['values'] and not isinstance(self.resources[target_resource]['values'][ref_type], list):
                        defaults = Defaults()
                        console_write('{} {}: {}'.format(defaults.warning_icon,
                                    defaults.warning_colour('WARNING'),
                                    defaults.info_colour('Source resource {}, target resource {} ref type "{}" is not a list. Parameter: {} '
                                                         'The value is: "{}"'.format(source_resource, target_resource, ref_type, parameter, self.resources[target_resource]['values'][ref_type]))))

we can see that the failing run logs following warnings

❗ WARNING (mounting): The reference "module.data-common" in resource module.component.aws_security_group.example_sg is ambiguous. It will not be mounted.
❗ WARNING (test): Injecting string into "ingress" parameter... Source resource module.component.module.nested-component.aws_security_group.example_sg_nested_client, target resource module.component.aws_security_group.example_sg ref type "aws_security_group".
❗ WARNING (test): Injecting string into "ingress" parameter... Source resource module.component.module.nested-component.aws_security_group.example_sg_nested_host, target resource module.component.aws_security_group.example_sg ref type "aws_security_group".
❗ WARNING (test): Injecting string into "ingress" parameter... Source resource module.component.module.nested-component.aws_security_group_rule.example_sg_nested_client_egress_host, target resource module.component.aws_security_group.example_sg ref type "aws_security_group_rule".
❗ WARNING (test): Injecting string into "ingress" parameter... Source resource module.component.module.nested-component.aws_security_group_rule.example_sg_nested_host_ingress_client, target resource module.component.aws_security_group.example_sg ref type "aws_security_group_rule".
❗ WARNING (test): Injecting string into "security_group_id" parameter... Source resource module.component.module.nested-component.aws_security_group_rule.example_sg_nested_client_egress_host, target resource module.component.module.nested-component.aws_security_group.example_sg_nested_client ref type "egress".
❗ WARNING (test): Injecting string into "source_security_group_id" parameter... Source resource module.component.module.nested-component.aws_security_group_rule.example_sg_nested_client_egress_host, target resource module.component.module.nested-component.aws_security_group.example_sg_nested_host ref type "egress".
❗ WARNING (test): Injecting string into "security_group_id" parameter... Source resource module.component.module.nested-component.aws_security_group.example_sg_nested_client, target resource module.component.module.nested-component.aws_security_group_rule.example_sg_nested_client_egress_host ref type "aws_security_group".
❗ WARNING (test): Injecting string into "source_security_group_id" parameter... Source resource module.component.module.nested-component.aws_security_group.example_sg_nested_host, target resource module.component.module.nested-component.aws_security_group_rule.example_sg_nested_client_egress_host ref type "aws_security_group".
❗ WARNING: Source resource module.component.module.nested-component.aws_security_group_rule.example_sg_nested_host_ingress_client, target resource module.component.module.nested-component.aws_security_group.example_sg_nested_host ref type "ingress" is not a list. Parameter: security_group_id The value is: "module.component.aws_security_group.example_sg"

where the successful run logs following

❗ WARNING (test): Injecting string into "security_group_id" parameter... Source resource module.component.module.nested-component.aws_security_group_rule.example_sg_nested_client_egress_host, target resource module.component.module.nested-component.aws_security_group.example_sg_nested_client ref type "egress".
❗ WARNING (test): Injecting string into "source_security_group_id" parameter... Source resource module.component.module.nested-component.aws_security_group_rule.example_sg_nested_client_egress_host, target resource module.component.module.nested-component.aws_security_group.example_sg_nested_host ref type "egress".
❗ WARNING (test): Injecting string into "security_group_id" parameter... Source resource module.component.module.nested-component.aws_security_group.example_sg_nested_client, target resource module.component.module.nested-component.aws_security_group_rule.example_sg_nested_client_egress_host ref type "aws_security_group".
❗ WARNING (test): Injecting string into "source_security_group_id" parameter... Source resource module.component.module.nested-component.aws_security_group.example_sg_nested_host, target resource module.component.module.nested-component.aws_security_group_rule.example_sg_nested_client_egress_host ref type "aws_security_group".
❗ WARNING (test): Injecting string into "security_group_id" parameter... Source resource module.component.module.nested-component.aws_security_group_rule.example_sg_nested_host_ingress_client, target resource module.component.module.nested-component.aws_security_group.example_sg_nested_host ref type "ingress".
❗ WARNING (test): Injecting string into "source_security_group_id" parameter... Source resource module.component.module.nested-component.aws_security_group_rule.example_sg_nested_host_ingress_client, target resource module.component.module.nested-component.aws_security_group.example_sg_nested_client ref type "ingress".
❗ WARNING (test): Injecting string into "security_group_id" parameter... Source resource module.component.module.nested-component.aws_security_group.example_sg_nested_host, target resource module.component.module.nested-component.aws_security_group_rule.example_sg_nested_host_ingress_client ref type "aws_security_group".
❗ WARNING (test): Injecting string into "source_security_group_id" parameter... Source resource module.component.module.nested-component.aws_security_group.example_sg_nested_client, target resource module.component.module.nested-component.aws_security_group_rule.example_sg_nested_host_ingress_client ref type "aws_security_group".

We can quickly tell that when we're using the my-data-module the ingress parameter is injected into all resources from my-nested-module (including security groups) and this is probably what's causing the issue as on the subsequent runs we do not expect string here

self.resources[target_resource]['values'][ref_type].append(resource)

from cli.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.