Skip to content

Conversation

@madpipeline
Copy link

@madpipeline madpipeline commented Jul 29, 2025

Description

Allow for setting or not setting the logging dynamically using a conditional statement.

Motivation and Context

locals {
  is_production = terraform.workspace == "prod" ? true : false
}

module "s3_bucket" {
  source  = "terraform-aws-modules/s3-bucket/aws"
  [...]

  logging = local.is_production ? {
    target_bucket = module.logs_bucket.s3_bucket_id
    target_prefix = "s3-access-logs/${module.logs_bucket.s3_bucket_id}/"
    target_object_key_format = {
      partitioned_prefix = {
        partition_date_source = "EventTime"
      }
    }
  } : {}

When using terraform workspaces, we need to only enable S3 logging in production, or other specific environments, this currently cannot be achieved and was reported in multiple issues, without any answer from the community: #314, #287, #153. Indeed the approach described in those issues could easily be resolved using the wrapper module, but for using terraform workspaces the same solution is not straight forward nor clean.

Currently we run into a type mismatch:

Error: Inconsistent conditional result types
The true and false result expressions must have consistent types. The 'true' value includes object attribute "target_bucket", which is absent in the 'false' value.

An alternative that is accepted by terraform syntax, is to pass null instead of {}, but this fails because the module searches for the keys of the var.logging variable directly, and breaks with:

│ Error: Invalid function argument
│
│   on .terraform/modules/s3_bucket/main.tf line 51, in resource "aws_s3_bucket_logging" "this":
│   51:   count = local.create_bucket && length(keys(var.logging)) > 0 && !var.is_directory_bucket ? 1 : 0
│     ├────────────────
│     │ while calling keys(inputMap)
│     │ var.logging is null
│
│ Invalid value for "inputMap" parameter: argument must not be null.

Thus wrapping the keys() call in a try() block, to capture this would resolve the issue with 0 impact in other scenarios.

Breaking Changes

There are no breaking changes.

How Has This Been Tested?

  • I have updated at least one of the examples/* to demonstrate and validate my change(s)
  • I have tested and validated these changes using one or more of the provided examples/* projects
  • I have executed pre-commit run -a on my pull request

@madpipeline madpipeline changed the title Allow for dynamic optional logging fix: Allow for dynamic optional logging Jul 29, 2025
@antonbabenko
Copy link
Member

This is not a problem with the module itself, but rather how Terraform works. Try something like this:

locals {
  log = {
    target_bucket = module.logs_bucket.s3_bucket_id
    target_prefix = "s3-access-logs/${module.logs_bucket.s3_bucket_id}/"
    target_object_key_format = {
      partitioned_prefix = {
        partition_date_source = "EventTime"
      }
    }
  }
}

module "s3_bucket" {
  # ...
  logging = { for k,v in local.log: k => v if local.is_production }
}

@github-actions
Copy link

I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 29, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants