Module output into locals for different module

Hi guys.

I’m writing modules for one of our project and I have the following situation. The first module is elastic beanstalk with locals and the second one is for aws_iam_role. My folder structure is below:

-modules/
  -- module-1
      -- main.tf
      -- outputs.tf
      -- locals.tf
  --module-2
     -- main.tf
     -- outputs.tf
     -- locals.tf
main.tf
outputs.tf
locals.tf

For my elastic beanstalk module I have the following locals defined with aws_iam_role resource"

modules/module-1

       ...
       namespace = "aws:autoscaling:launchconfiguration"
       name      = "IamInstanceProfile"
       value     = aws_iam_role.app_role.name # How to pass the name attribute from aws_iam role here?
       resource  = ""
       },{
     ## Security
       namespace = "aws:autoscaling:launchconfiguration"
       name      = "IamInstanceProfile"
       value     = aws_iam_role.app_role.name # How to pass the name attribute from aws_iam role here?
       resource  = ""
       }, {
      ...

modules/module-2

In the second module folder I have outputs.tf with the content below:

output "iam_role_name" {
  value = "${aws_iam_role.app_role.name}"
}

Also the main.tf file like below

resource "aws_iam_instance_profile" "app_instance_profile" {
  provider = aws.alias
  name     = "${local.resource_name_prefix}-role"
  role     = "${aws_iam_role.app_role.name}"
}


resource "aws_iam_role" "app_role" {
  provider = aws.alias
  name     = "${local.resource_name_prefix}-role"
  managed_policy_arns = [
    "arn:aws:iam::aws:policy/AWSElasticBeanstalkTier",
  ]
  assume_role_policy = jsonencode(
    {
      Statement = [
        {
          Action = "sts:AssumeRole"
          Effect = "Allow"
          Principal = {
            Service = [
              "lambda.amazonaws.com",
              "ec2.amazonaws.com",
            ]
          }
        },
      ]
      Version = "2012-10-17"
    }
  )
  inline_policy {
    name = "SM"
    policy = jsonencode(
      {
        Statement = [
          {
            Action = [
              "secretsmanager:GetResourcePolicy",
              "secretsmanager:GetSecretValue",
              "secretsmanager:DescribeSecret",
              "secretsmanager:ListSecretVersionIds",
            ]
            Effect   = "Allow"
            Resource = aws_secretsmanager_secret.app_secret.arn
          },
          {
            Action = [
              "secretsmanager:GetRandomPassword",
              "secretsmanager:ListSecrets",
            ]
            Effect   = "Allow"
            Resource = "*"
          },
        ]
        Version = "2012-10-17"
      }
    )
  }
}

In my root folder I have the following main.tf

module "aws_iam_role" {
  source = "../modules/module-1"

  providers = {
    aws.alias= aws.alias
  }

}

module "eb_api" {
  source = "../modules/module-2"

    providers = {
    aws.alias= aws.alias
  }
}

I need to pass the name attribute from iam_role_name as input to elastic beanstalk locals. Any help?

Regards,

Just as you have to create an output from the first module, if you want to pass something in to a module, you’ll need to make an input variable (following the usual convention, this would typically live in variables.tf), and call module2 with that as a variable. You can do further mangling of that variable in a local variable if needed.

So you’d end up with

module "eb_api" {
  source = "../modules/module-2"

  providers = {
    aws.alias= aws.alias
  }
  some_variable = module.aws_iam_role.iam_role_name
}
1 Like