Skip to content

Accept null value for replication_configuration variable #285

@trc-smoehn

Description

@trc-smoehn

Description

With the current setup it is not possible to conditionally configure an S3 Bucket with replication_configuration.
The true and false result expressions can't have consistent types, because the module code is not designed for that.

If the condition is true (replication_configuration should be defined), then an empty object ({}) as false result is not accepted and raises a Terraform error The true and false result expressions must have consistent types. The 'true' value includes object attribute "role", which is absent in the 'false' value., only null is possible.

If the condition is false (replication_configuration should not be defined), null is not accepted by the module code, resulting in the error Invalid value for "inputMap" parameter: argument must not be null..

Versions

  • Module version [Required]: 4.1.2
  • Terraform version: Terraform v1.9.4 on darwin_arm64
  • Provider version(s):
    • provider registry.terraform.io/hashicorp/aws v5.63.1
    • provider registry.terraform.io/hashicorp/random v3.6.2

Reproduction Code [Required]

resource "random_integer" "random" {
  min = 1000
  max = 9999
}

locals {
  use_bucket_replication01 = true
  use_bucket_replication02 = false
}

module "s3_replication" {
  source  = "terraform-aws-modules/s3-bucket/aws"
  version = "4.1.2"

  # General
  bucket = "replication-${random_integer.random.id}"

  # Versioning
  versioning = {
    enabled = true
  }

  # Replication
  replication_configuration = local.use_bucket_replication01 ? {
    role = aws_iam_role.replication_dummy_role.arn

    rules = [
      {
        id       = "replicate"
        status   = true
        priority = 10

        delete_marker_replication = false

        source_selection_criteria = {
          replica_modifications = {
            status = "Enabled"
          }
          sse_kms_encrypted_objects = {
            enabled = true
          }
        }

        destination = {
          bucket = "arn:aws:s3:::target-${random_integer.random.id}"
        }
      }
    ]
  } : {}
}

module "s3_no_replication" {
  source  = "terraform-aws-modules/s3-bucket/aws"
  version = "4.1.2"

  # General
  bucket = "no-replication-${random_integer.random.id}"

  # Versioning
  versioning = {
    enabled = true
  }

  # Replication
  replication_configuration = local.use_bucket_replication02 ? {
    role = aws_iam_role.replication_dummy_role.arn

    rules = [
      {
        id       = "replicate"
        status   = true
        priority = 10

        delete_marker_replication = false

        source_selection_criteria = {
          replica_modifications = {
            status = "Enabled"
          }
          sse_kms_encrypted_objects = {
            enabled = true
          }
        }

        destination = {
          bucket = "arn:aws:s3:::target-${random_integer.random.id}"
        }
      }
    ]
  } : null
}

module "s3_target" {
  source  = "terraform-aws-modules/s3-bucket/aws"
  version = "4.1.2"

  # General
  bucket = "target-${random_integer.random.id}"

  # Versioning
  versioning = {
    enabled = true
  }
}

resource "aws_iam_role" "replication_dummy_role" {
  name = "s3-bucket-replication-${random_integer.random.id}"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Sid    = ""
        Principal = {
          Service = "s3.amazonaws.com"
        }
      },
    ]
  })

  inline_policy {
    name = "s3"

    policy = jsonencode({
      Version = "2012-10-17"
      Statement = [
        {
          Action   = ["s3:*"]
          Effect   = "Allow"
          Resource = "*"
        },
      ]
    })
  }
}

Steps to reproduce the behavior:

  • Init and Apply
  • Module "s3_replication" has an empty object as false condition and module "s3_no_replication" has null as false condition

Expected behavior

The module should accept null as value for the replication_configuration variable and check if the variable is null on the resource aws_s3_bucket_replication_configuration. Also it should set null as default value for the variable instead of {}.

Actual behavior

The module checks for length(keys(var.replication_configuration)) > 0 on resource aws_s3_bucket_replication_configuration, but giving an empty object as variable input produces "inconsistent types" error

Terminal Output Screenshot(s)

Screenshot 2024-08-21 at 11 00 57

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions