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

Cannot set null/undefined value for aws_s3_bucket lifecycle_rule expiration days #1544

Closed
kevinchn opened this issue Aug 30, 2017 · 2 comments
Labels
bug Addresses a defect in current functionality. service/s3 Issues and PRs that pertain to the s3 service.

Comments

@kevinchn
Copy link

kevinchn commented Aug 30, 2017

Terraform Version

v0.10.2

Affected Resource(s)

  • aws_s3_bucket

Terraform Configuration Files

provider "aws" {
  access_key = "xxx"
  secret_key = "xxx"
  region     = "us-east-1"
}

resource "aws_s3_bucket" "bucket" {
  bucket = "xxxx"

  lifecycle_rule = {
    prefix = ""
    enabled = "true"
    expiration = {
      days = "0"
    }
  }
}

Debug Output

https://gist.github.com/kevinchn/49d5a846acc822e630f1bc8479508be9

Panic Output

Expected Behavior

Since Terraform doesn't support a null/undefined value, resources should accept a "zero" value as unset according to this comment by mitchellh
This is necessary when expiration days is a variable.
The previous behavior on v.0.9.11 is that an empty lifecycle rule was created (without any expirations)

Actual Behavior

A Terraform validation error is thrown

* aws_s3_bucket.bucket: "lifecycle_rule.0.expiration.0.days" must be greater than 0

Setting days = "" also doesn't work (with error: cannot parse '' as int: strconv.ParseInt: parsing "": invalid syntax)

Steps to Reproduce

  1. Only need the Terraform configuration provided above
  2. Run terraform init and terraform apply

Important Factoids

We did not get this error on v.0.9.11.

References

hashicorp/terraform#5471 (comment)
It appears this validation was added in the PR #957

@Ninir Ninir added the bug Addresses a defect in current functionality. label Aug 30, 2017
@radeksimko radeksimko added the service/s3 Issues and PRs that pertain to the s3 service. label Jan 28, 2018
@bflad
Copy link
Contributor

bflad commented Jul 24, 2019

Hi folks 👋 This issue is resolved in Terraform 0.12, which supports new functionality in the configuration language aimed at solving this issue. The new null value can be used to omit arguments as if they were not defined in the configuration at all. For doing similar with configuration blocks, please see the new dynamic block syntax.

Since expiration is a configuration block we will want to ensure that we handle it via dynamic and not just a null argument value on days, although the concepts can be combined if necessary as shown below.

Given this configuration:

variable "test1" {
  type = list(object({
    date = string
    days = number
  }))
  default = [{
    date = "2020-01-01"
    days = null
  }]
}

variable "test2" {
  type = list(object({
    date = string
    days = number
  }))
  default = [{
    date = null
    days = 10
  }]
}

resource "aws_s3_bucket" "test1" {
  bucket = "tf-test1-1544"

  lifecycle_rule {
    enabled = true
    id      = "test"
    prefix  = "test/"

    dynamic "expiration" {
      for_each = var.test1

      content {
        date = expiration.value.date
        days = expiration.value.days
      }
    }
  }
}

resource "aws_s3_bucket" "test2" {
  bucket = "tf-test2-1544"

  lifecycle_rule {
    enabled = true
    id      = "test"
    prefix  = "test/"

    dynamic "expiration" {
      for_each = var.test2

      content {
        date = expiration.value.date
        days = expiration.value.days
      }
    }
  }
}

Produces the following apply output:

$ terraform apply

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_s3_bucket.test1 will be created
  + resource "aws_s3_bucket" "test1" {
      + acceleration_status         = (known after apply)
      + acl                         = "private"
      + arn                         = (known after apply)
      + bucket                      = "tf-test1-1544"
      + bucket_domain_name          = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + lifecycle_rule {
          + enabled = true
          + id      = "test"
          + prefix  = "test/"

          + expiration {
              + date = "2020-01-01"
            }
        }

      + versioning {
          + enabled    = (known after apply)
          + mfa_delete = (known after apply)
        }
    }

  # aws_s3_bucket.test2 will be created
  + resource "aws_s3_bucket" "test2" {
      + acceleration_status         = (known after apply)
      + acl                         = "private"
      + arn                         = (known after apply)
      + bucket                      = "tf-test2-1544"
      + bucket_domain_name          = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + lifecycle_rule {
          + enabled = true
          + id      = "test"
          + prefix  = "test/"

          + expiration {
              + days = 10
            }
        }

      + versioning {
          + enabled    = (known after apply)
          + mfa_delete = (known after apply)
        }
    }

Plan: 2 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_s3_bucket.test1: Creating...
aws_s3_bucket.test2: Creating...
aws_s3_bucket.test2: Creation complete after 1s [id=tf-test2-1544]
aws_s3_bucket.test1: Creation complete after 2s [id=tf-test1-1544]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Enjoy! 🚀

@bflad bflad closed this as completed Jul 24, 2019
@ghost
Copy link

ghost commented Nov 2, 2019

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

@ghost ghost locked and limited conversation to collaborators Nov 2, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Addresses a defect in current functionality. service/s3 Issues and PRs that pertain to the s3 service.
Projects
None yet
Development

No branches or pull requests

4 participants