Help needed : output variable empty

Hello community,

I spend 10 hours to try to understand why the output value of a ressource is empty without success.

The structure of me folder is :

  • tf
    • main.tf
    • outputs.tf
    • variables.tf
    • terraform.tfvars
    • modules/
      • share/
        • iam/
          • main.tf
          • outputs.tf
          • variables.tf
      • integration/
        • main.tf
        • variables.tf
        • outputs.tf
        • lambda/
          • main.tf
          • variables.tf
          • outputs.tf

I would like to pass output from tf/modules/share/iam/outputs.tf from tf/modules/integration/lambda/main.tf

In tf/modules/integration/lambda/main.tf

resource "aws_iam_role" "lambda_role" {
  name        = "${var.project_name}_lambda_role"
  description = "${var.project_name} : lambda access"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": [
          "lambda.amazonaws.com",
          "apigateway.amazonaws.com"
        ]
      },
      "Effect": "Allow",
      "Sid": "LambdaAssumeRole"
    }
  ]
}
EOF
}

In tf/modules/integration/lambda/outputs.tf

output "iam_lambda_role_arn" {
  description = "ARN of the lambda execution role"
  value       = aws_iam_role.lambda_role.arn
}

In tf/main.tf

module "share_iam" {
  source = "./modules/share/iam"
  # variable send to module
}

module "integration" {
  source                    = "./modules/integration"
  # variable send to module
  share_iam_lambda_role_arn = module.share_iam.iam_lambda_role_arn
  
}

in tf/modules/integration/variables.tf

variable "share_iam_lambda_role_arn" {
  type    = string
  default = ""
}

In tf/modules/integration/main.tf

module "lambda" {
  source                    = "./lambda"
  share_iam_lambda_role_arn = var.share_iam_lambda_role_arn
}

then in tf/modules/integration/lambda/variables.tf

variable "share_iam_lambda_role_arn" {
  type    = string
  default = ""
}

and in tf/modules/integration/lambda/main.tf

resource "aws_lambda_function" "entry_process_add" {
   ...
  role          = var.share_iam_lambda_role_arn
  ...
}

You know everything !!
Terraform validate + terraform plan have no error code
But when I do an apply, I have this error :slight_smile:

Error: creating Lambda Function (entry_process_add): operation error Lambda: CreateFunction, https response error StatusCode: 400, RequestID: e46d89ea-9265-4f09-b54c-80a1114bdbba, api error ValidationException: 1 validation error detected: Value '' at 'role' failed to satisfy constraint: Member must satisfy regular expression pattern: arn:(aws[a-zA-Z-]*)?:iam::\d{12}:role/?[a-zA-Z_0-9+=,.@\-_/]+
│ 
│   with module.integration.module.apigateway.module.lambda.aws_lambda_function.entry_process_add,
│   on modules/integration/lambda/main.tf line 5, in resource "aws_lambda_function" "entry_process_add":
│    5: resource "aws_lambda_function" "entry_process_add" {

The value of “var.share_iam_lambda_role_arn” is empy but the ressource "resource “aws_iam_role” “lambda_role” has been well created in AWS

Hello, I believe the issue is related to the execution order.

Unfortunately, Terraform does not handle dependency processing between module calls when we have two or more modules being invoked.

I can suggest three alternatives:

  1. Place the role logic within the Lambda module so that it resolves internally.
  2. Try using depends_on to see if you can explicitly manage it.
  3. Use phased Terraform plan/apply, using -target=module.share_iam to do the plan and apply first, and then perform the full plan/apply.

Personally, I think option 1) is the most promising, as the dependency between modules and resources works very well.