Skip to content

aws_s3_object: opt-in replacement on tag changes (tags_trigger_replace) #47801

@abjones

Description

@abjones

Description

Summary

Add an optional argument to aws_s3_object (for example, tags_trigger_replace) that allows users to opt into full object replacement when tags change, including when tags are modified or removed out‑of‑band (e.g., via the AWS Console or services like AWS Glue).

Default behavior would remain unchanged.


Motivation

S3 object tags are frequently modified or reset by AWS-managed workflows and console actions. A common example is AWS Glue, which can overwrite S3 objects and clear their tags without changing the object content.

Today, when tag drift is detected for aws_s3_object, the provider reconciles tags in place using PutObjectTagging. While this is correct for many use cases, it is problematic for users who:

  • Treat S3 objects as immutable artifacts (scripts, binaries, Glue jobs, Lambda layers)
  • Use tags as part of an ownership or integrity contract
  • Expect any drift to result in full reconciliation of the object, not partial repair

The provider already supports replacement semantics when content changes (e.g., via source_hash or etag). Extending this opt‑in replacement model to tags would make behavior more consistent and give users better control.


Proposed Behavior

Introduce a new optional argument:

tags_trigger_replace = false

When set to true:

  • Any difference in tags (add, remove, or change)
  • Including tag drift detected during refresh
  • Would cause the S3 object to be destroyed and recreated (ForceNew)
  • Instead of performing an in‑place tag update

When set to false (default):

  • Behavior is unchanged
  • Tag differences are reconciled in place

If tags are removed or modified outside of Terraform, the next plan would show a -/+ replacement instead of an in‑place update.


Implementation Notes (for Maintainers)

  • This can be implemented at diff time using CustomizeDiff
  • When tags_trigger_replace is true and tags has a diff, the diff can be marked ForceNew
  • This approach:
    • Does not affect update logic
    • Preserves existing default‑tag handling
    • Is fully backward compatible
  • Similar opt‑in replacement flags already exist in the provider (e.g., user_data_replace_on_change)

Why This Cannot Be Solved in Configuration Alone

Terraform/OpenTofu configuration cannot override a provider’s choice of update‑in‑place vs replace when reacting to detected drift. Lifecycle meta‑arguments only respond to configuration changes, not provider‑detected remote differences.

As a result, this behavior can only be implemented cleanly within the provider.


Backward Compatibility

  • Default behavior unchanged
  • Opt‑in only
  • No state migration required

Use Cases

  • AWS Glue jobs resetting S3 object tags
  • Enforcing immutability for S3‑hosted artifacts
  • Defense‑in‑depth against silent metadata drift
  • Clear declarative ownership boundaries

Affected Resource(s) or Data Source(s)

aws_s3_object

Potential Terraform Configuration

resource "aws_s3_object" "example" {
  bucket = "example-bucket"
  key    = "glue/scripts/job.py"
  source = "job.py"

  source_hash = filebase64sha256("job.py")

  tags = {
    ManagedBy = "terraform"
    Purpose   = "glue-job"
  }

  tags_trigger_replace = true
}

References

No response

Would you like to implement the enhancement?

No

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementRequests to existing resources that expand the functionality or scope.needs-triageWaiting for first response or review from a maintainer.service/s3Issues and PRs that pertain to the s3 service.tagsPertains to resource tagging.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions