Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

S3 BucketLifecycleConfigurationV2RuleArgs Expiration is not deleted when set to nil #4469

Open
cooloncoolon opened this issue Sep 18, 2024 · 2 comments
Labels
awaiting-feedback Blocked on input from the author kind/bug Some behavior is incorrect or out of spec

Comments

@cooloncoolon
Copy link

cooloncoolon commented Sep 18, 2024

Describe what happened

we are implementing S3 Lifecycle policy for our S3 buckets and noticed that all lifecycle policy configuration works as expected except "Expiration" when 'nil' is passed to this field. We are expecting that the Expiration configuration is removed from the rule configuration but the preview shows no objects to be changed. At the same time the "Expiration" works when creating or updating(ex. changing number of days).

we have the same configuration for the "NoncurrentVersionExpiration" but in this case the configuration block works as expected - created, updated and removed.

moreover the "Expiration" configuration is removed if there are another rule changes at the same time. but it is removed silently, preview does not shows any diff for the "Expiration" configuration.

Sample program

type LifecyclePolicyRulesArgs struct {
	RuleIdSuffix                                 string
	RuleStatus                                   string
	ObjectsFilterOptions                         ObjectsFilterOptionsArgs
	ObjectsIncompleteMultipartUploadAbortOptions *ObjectsIncompleteMultipartUploadAbortOptionsArgs
	ObjectsTransitionRulesOptions                ObjectsTransitionRulesOptionsArgs
	ObjectsExpirationRuleOptions                 *ObjectsExpirationRuleOptionsArgs
	NonCurrentVersionsTransitionRulesOptions     NonCurrentVersionsTransitionRulesOptionsArgs
	NonCurrentVersionsExpirationRuleOptions      *NonCurrentVersionsExpirationRuleOptionsArgs
}

// S3 Bucket Lifecycle Rules configuration - Objects expiration
type ObjectsExpirationRuleOptionsArgs struct {
	AfterDays                  int
	AfterDate                  string
	IsExpireObjectDeleteMarker bool
}

// S3 Bucket Lifecycle Rules configuration - Noncurrent Versions expiration
type NonCurrentVersionsExpirationRuleOptionsArgs struct {
	AfterDays          int
	RetainNonCurVerQty string
}

func (args *BucketArgs) createS3LifecycleConfig(ctx *pulumi.Context) error {
	
	// Convert S3 Lyfecycle Rules configuration to s3.BucketLifecycleRule format
	var s3LifecyclePolicyRules s3.BucketLifecycleConfigurationV2RuleArray
	for _, lifecycleRules := range args.LifecyclePolicyOptions.Rules {

		// Parse and convert S3 Objects Expiration Rules configuration
		var s3ObjectsExpirations *s3.BucketLifecycleConfigurationV2RuleExpirationArgs
		if lifecycleRules.ObjectsExpirationRuleOptions != nil {
			s3ObjectsExpirations = &s3.BucketLifecycleConfigurationV2RuleExpirationArgs{
				Days:                      pulumi.Int(lifecycleRules.ObjectsExpirationRuleOptions.AfterDays),
				ExpiredObjectDeleteMarker: pulumi.Bool(lifecycleRules.ObjectsExpirationRuleOptions.IsExpireObjectDeleteMarker),
			}
		}

		// Build S3 Lifecycle Policy Rule
		s3LifecyclePolicyRules = append(s3LifecyclePolicyRules, s3.BucketLifecycleConfigurationV2RuleArgs{
			Status:                         pulumi.String(lifecycleRules.RuleStatus),
			Id:                             pulumi.String("s3-lifecycle-rule-" + args.BucketName + "_" + lifecycleRules.RuleIdSuffix),
			Filter:                         s3ObjectsFilters,
			AbortIncompleteMultipartUpload: s3ObjectsIncompleteMultipartUploadAbort,
			Transitions:                    s3ObjectsTransitions,
			NoncurrentVersionTransitions:   s3NonCurVerTransitions,
			NoncurrentVersionExpiration:    s3NonCurVerExpirations,
			Expiration:                     s3ObjectsExpirations,
		})
	}
	// Create S3 Lifecycle Policy Rule
	_, err := s3.NewBucketLifecycleConfigurationV2(ctx, "s3-lifecycle-policy-"+args.BucketName, &s3.BucketLifecycleConfigurationV2Args{
		Bucket: args.internal.Bucket.ID(),
		Rules:  s3LifecyclePolicyRules,
	})

	if err != nil {
		return err
	}
	return nil
}

Log output

No response

Affected Resource(s)

s3.NewBucketLifecycleConfigurationV2 Expiration

Output of pulumi about

CLI
Version 3.132.0
Go Version go1.23.1
Go Compiler gc

Plugins
KIND NAME VERSION
resource aws 5.24.0
language go 3.132.0
resource kubernetes 3.30.2

Host
OS darwin
Version 14.6.1
Arch arm64

This project is written in go: executable='/opt/homebrew/bin/go' version='go version go1.23.1 darwin/arm64'

Dependencies:
NAME VERSION
github.com/lib/pq v1.10.9
github.com/pulumi/pulumi-aws/sdk/v5 v5.24.0
github.com/pulumi/pulumi-kubernetes/sdk/v3 v3.30.2
github.com/pulumi/pulumi/sdk/v3 v3.81.0
github.com/stretchr/testify v1.8.3

Additional context

lifecycle policy configuration declared as follows:

testing rule array

  lifecyclePolicyOptions:
    enabled: true
    rules:
    #rule №1
    #- ruleStatus: Enabled
      #ruleIdSuffix: "lifecycle_for_IncompleteMultipartUploadAbort"
      #objectsIncompleteMultipartUploadAbortOptions:
        #afterDays: 15
    #rule №2
    #- ruleStatus: Enabled
      #ruleIdSuffix: "lifecycle_for_ExpireObjectDeleteMarker"
      #objectsExpirationRuleOptions:
        #isExpireObjectDeleteMarker: true
    #rule №3
    #- ruleStatus: Enabled
      #ruleIdSuffix: "lifecycle_for_expire_tag_logs"
      #objectsFilterOptions:
        #tags:
          #rule: "log"
          #autoclean: "true"
      #objectsExpirationRuleOptions:
        #afterDays: 90
    #rule №4
    #- ruleStatus: Enabled
      #ruleIdSuffix: "lifecycle_for_transition"
      #objectsFilterOptions:
        #prefix: "log/"
        #sizeGreaterThan: 132000
        #sizeLessThan: 133000
      #objectsTransitionRulesOptions:
        #rules:
        #- afterDays: 30 
          #afterDate: "2025-01-01T00:00:00Z"
          #toStorageClass: "STANDARD_IA"
        #- afterDays: 60
          #afterDate: "2026-01-02T00:00:00Z"
          #toStorageClass: "GLACIER"
    #rule №5
    #- ruleStatus: Enabled
      #ruleIdSuffix: "lifecycle_for_noncurrentversions"
      #nonCurrentVersionsTransitionRulesOptions:
        #rules:
        #- afterDays: 30 
          #toStorageClass: "STANDARD_IA"
          #retainNonCurVerQtyAfterTransition: "7"
        #- afterDays: 60
          #toStorageClass: "GLACIER"
          #retainNonCurVerQtyAfterTransition: "7"
      #nonCurrentVersionsExpirationRuleOptions:
          #retainNonCurVerQty: "7"
          #afterDays: 90    
    #rule №6
    - ruleStatus: Enabled
      ruleIdSuffix: "lifecycle_for_transition"
      #objectsIncompleteMultipartUploadAbortOptions:
        #afterDays: 15
      #objectsFilterOptions:
        #prefix: "log/"
        #sizeGreaterThan: 132000
        #sizeLessThan: 133000
        #tags:
          #rule_1: "log_1"
          #autoclean_1: "true_1"
        #tag:
          #key: "log_1"
          #value: "true_1"
      objectsTransitionRulesOptions:
        rules:
        - afterDays: 30 
          #afterDate: "2025-01-02T00:00:00Z"
          toStorageClass: "STANDARD_IA"
        - afterDays: 60
          #afterDate: "2026-01-03T00:00:00Z"
          toStorageClass: "GLACIER"
      #objectsExpirationRuleOptions:
        #afterDays: 90
      #nonCurrentVersionsTransitionRulesOptions:
        #rules:
        #- afterDays: 30 
          #toStorageClass: "STANDARD_IA"
          #retainNonCurVerQtyAfterTransition: "7"
        #- afterDays: 60
          #toStorageClass: "GLACIER"
          #retainNonCurVerQtyAfterTransition: "7"
      #nonCurrentVersionsExpirationRuleOptions:
        #retainNonCurVerQty: "7"
        #afterDays: 90
      
     testing rule array

Contributing

Vote on this issue by adding a 👍 reaction.
To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

@cooloncoolon cooloncoolon added kind/bug Some behavior is incorrect or out of spec needs-triage Needs attention from the triage team labels Sep 18, 2024
@corymhall
Copy link
Contributor

@cooloncoolon it looks like from the about info you are on a previous major version v5. Can you try upgrading to v6 and see if you still have the same issue?

@corymhall corymhall added awaiting-feedback Blocked on input from the author and removed needs-triage Needs attention from the triage team labels Sep 19, 2024
@cooloncoolon
Copy link
Author

hi @corymhall ,
ill give a try v6 and get back with the results

@pulumi-bot pulumi-bot added needs-triage Needs attention from the triage team and removed awaiting-feedback Blocked on input from the author labels Sep 19, 2024
@corymhall corymhall added awaiting-feedback Blocked on input from the author and removed needs-triage Needs attention from the triage team labels Sep 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting-feedback Blocked on input from the author kind/bug Some behavior is incorrect or out of spec
Projects
None yet
Development

No branches or pull requests

3 participants