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

aws_backup_plan lifecycle cold_storage_after should be optional #8151

Closed
sbutler opened this issue Apr 2, 2019 · 11 comments · Fixed by #8236
Closed

aws_backup_plan lifecycle cold_storage_after should be optional #8151

sbutler opened this issue Apr 2, 2019 · 11 comments · Fixed by #8236
Labels
bug Addresses a defect in current functionality. documentation Introduces or discusses updates to documentation. service/backup Issues and PRs that pertain to the backup service.
Milestone

Comments

@sbutler
Copy link
Contributor

sbutler commented Apr 2, 2019

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform Version

Terraform v0.11.13

  • provider.aws v2.4.0

Affected Resource(s)

  • aws_backup_plan

Terraform Configuration Files

resource "aws_backup_vault" "example" {
    name = "example-vault"
}

resource "aws_backup_plan" "example" {
    name = "example-plan"
    rule {
        rule_name = "MainRule"
        target_vault_name = "${aws_backup_vault.example.name}"
        schedule = "cron(5 8 * * ? *)"
        lifecycle {
            delete_after = 30
        }
    }
}

Debug Output

https://gist.github.com/sbutler/f9480ef8e86428b054181b94d6221a75

Expected Behavior

I should be able to create a plan with a rule that only has delete_after and no cold_storage_after.

Actual Behavior

Plan fails, because the request terraform sends is invalid (delete_after not 90 days after cold_storage_after).

Steps to Reproduce

  1. terraform apply

References

@nywilken nywilken added service/backup Issues and PRs that pertain to the backup service. bug Addresses a defect in current functionality. documentation Introduces or discusses updates to documentation. labels Apr 2, 2019
@nywilken
Copy link
Contributor

nywilken commented Apr 2, 2019

Hi @sbutler thanks for opening up this issue. Quickly looking at the resource code base I can see some inconsistencies around the documentation for the lifecycle attributes which are actually optional, but documented as Required. There also may be a case where we are sending a value for cold storage when we shouldn't be so I am adding the bug label to this issue for further investigation.

@ghost
Copy link

ghost commented Apr 4, 2019

I ran into this while working with the new service as well. It appears that both delete after and move to cold storage should be optional.

If cold storage is defined though, delete after must be > move to cold storage + 90.

AWS Backup API » Data Types » Lifecycle

@grom3k
Copy link
Contributor

grom3k commented Apr 6, 2019

Hey @kmcdowell85 @nywilken @slapula
After quick investigation I noticed that if one of the lifecycle attribute is left unspecified it gets value 0.

Example.
Resource definition:

resource "aws_backup_plan" "example" {
  provider = "awstest.debug"
  name     = "tf_example_backup_plan"

  rule {
    rule_name         = "tf_example_backup_rule"
    target_vault_name = "Default"
    schedule          = "cron(0 12 * * ? *)"

    lifecycle {
      delete_after = 7
    }
  }
}

Get some additional output:

diff --git a/aws/resource_aws_backup_plan.go b/aws/resource_aws_backup_plan.go
index 8c7f052b4..56e7e1170 100644
--- a/aws/resource_aws_backup_plan.go
+++ b/aws/resource_aws_backup_plan.go
@@ -111,6 +111,7 @@ func resourceAwsBackupPlanCreate(d *schema.ResourceData, meta interface{}) error
 
        resp, err := conn.CreateBackupPlan(input)
        if err != nil {
+               log.Printf("Current rules: %s", rules)
                return fmt.Errorf("error creating Backup Plan: %s", err)
        }
 

Rules list value:


2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest: 2019/04/06 12:11:59 [DEBUG] [aws-sdk-go] {"Code":"ERROR_3015","Context":"[\"tf_example_backup_rule\",\"Inva
lid lifecycle. DeleteAfterDays cannot be less than 90 days apart from MoveToColdStorageAfterDays\"]","Message":"Error in rule tf_example_backup_rule : Invalid lifecycle. DeleteAft
erDays cannot be less than 90 days apart from MoveToColdStorageAfterDays","Type":null}
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest: 2019/04/06 12:11:59 [DEBUG] [aws-sdk-go] DEBUG: Validate Response Backup/CreateBackupPlan failed, not retry
ing, error InvalidParameterValueException: Error in rule tf_example_backup_rule : Invalid lifecycle. DeleteAfterDays cannot be less than 90 days apart from MoveToColdStorageAfterD
ays
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest:         status code: 400, request id: 379ef015-56df-42cc-90fc-60ec6f80701e
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest: 2019/04/06 12:11:59 Current rules: [{
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest:   CompletionWindowMinutes: 180,
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest:   Lifecycle: {
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest:     DeleteAfterDays: 7,
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest:     MoveToColdStorageAfterDays: 0
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest:   },
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest:   RecoveryPointTags: {
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest: 
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest:   },
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest:   RuleName: "tf_example_backup_rule",
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest:   ScheduleExpression: "cron(0 12 * * ? *)",
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest:   StartWindowMinutes: 60,
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest:   TargetBackupVaultName: "Default"
2019-04-06T12:11:59.641+0200 [DEBUG] plugin.terraform-provider-awstest: }]

It applies to both delete_after and cold_storage_after

@slapula
Copy link
Contributor

slapula commented Apr 6, 2019

If I remember correctly, the Lifecycle struct doesn't let me leave this attribute empty thus the reason for the default value. I'm not sure if this is an issue with the API or the SDK at the moment. The alternative I thought of when I wrote this resource was to just tack on 90 days to the delete_after attribute if the other attribute was left undefined but decided against it since that was an assumption I was making for the operator. I can write that option up as a PR and see what the maintainers think when I have some free time. Is this like a huge blocker for people?

@grom3k
Copy link
Contributor

grom3k commented Apr 6, 2019

@slapula I've just did some tests and was able to successfully create backup plan while entirely omitting MoveToColdStorageAfterDays or DeleteAfterDays attribute.
To answer your question, I have a use case when I need to set DeleteAfterDays to 7 and leave MoveToColdStorageAfterDays "unspecified" resulting in following settings:

Never transition to cold storage
Expire after 1 week

@slapula
Copy link
Contributor

slapula commented Apr 6, 2019

@grom3k I saw your PR, thanks for catching that! Not sure why I didn't think about doing that in the first place 😁

@nywilken
Copy link
Contributor

nywilken commented Apr 6, 2019

@slapula @grom3k thanks for following up on this issue. The zero value check for this resource is the fix needed. There is also a documentation change that needs to happen as the attributes are currently marked as Required. I'm sorry for the delay on this, but I do have a fix with tests written up that I planned on PRing later today. I will open up the PR to help save @grom3k time. But I am happy to retract if you would like to continue with pushing this fix forward.

nywilken added a commit that referenced this issue Apr 6, 2019
Closes #8151

Lifecycle policies contain settings for deleting backups, and for moving
them to cold storage. A backup with cold storage enabled can not have a
deletion value lower then 90 days. So to prevent this AWS allows
setting ColdStorageAfter to Never by not setting a value for ColdSorageAfter.

This change add logic to ensure ColdSorageAfter and DeleteAfter only
get sent within the API request if the values are not empty and greater
than 0.

Acceptance Test before change
```
=== RUN   TestAccAwsBackupPlan_withLifecycle
=== PAUSE TestAccAwsBackupPlan_withLifecycle
=== RUN   TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
=== PAUSE TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
=== RUN   TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== PAUSE TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== CONT  TestAccAwsBackupPlan_withLifecycle
=== CONT  TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== CONT  TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
--- FAIL: TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly (10.86s)
    testing.go:538: Step 0 error: Error applying: 1 error occurred:
                * aws_backup_plan.test: 1 error occurred:
                * aws_backup_plan.test: error creating Backup Plan: InvalidParameterValueException: Error in rule tf_acc_test_backup_rule_lifecycle_policy_three : Invalid lifecycle. DeleteAfterDays cannot be less than one day
                status code: 400, request id: 757544c3-4628-4a7e-95fa-416098fe2594

--- FAIL: TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly (11.00s)
    testing.go:538: Step 0 error: Error applying: 1 error occurred:
                * aws_backup_plan.test: 1 error occurred:
                * aws_backup_plan.test: error creating Backup Plan: InvalidParameterValueException: Error in rule tf_acc_test_backup_rule_lifecycle_policy_two : Invalid lifecycle. DeleteAfterDays cannot be less than 90 days apart from MoveToColdStorageAfterDays
                status code: 400, request id: e37c0d06-0cd7-4783-b01a-40e1dc5758f0

--- PASS: TestAccAwsBackupPlan_withLifecycle (18.92s)
FAIL
FAIL    github.com/terraform-providers/terraform-provider-aws/aws       18.948s
GNUmakefile:20: recipe for target 'testacc' failed
```

Acceptance Test after change
```
=== RUN   TestAccAwsBackupPlan_withLifecycle
=== PAUSE TestAccAwsBackupPlan_withLifecycle
=== RUN   TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
=== PAUSE TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
=== RUN   TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== PAUSE TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== CONT  TestAccAwsBackupPlan_withLifecycle
=== CONT  TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== CONT  TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
--- PASS: TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly (18.70s)
--- PASS: TestAccAwsBackupPlan_withLifecycle (19.75s)
--- PASS: TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
(20.25s)
PASS
ok      github.com/terraform-providers/terraform-provider-aws/aws
20.266s
```
nywilken added a commit that referenced this issue Apr 7, 2019
Closes #8151

Lifecycle policies contain settings for deleting backups, and for moving
them to cold storage. A backup with cold storage enabled can not have a
deletion value lower then 90 days. So to prevent this AWS allows
setting ColdStorageAfter to Never by not setting a value for ColdStorageAfter.

This change adds logic to ensure ColdStorageAfter and DeleteAfter only
get sent within the API request if the values are not empty and greater
than 0.

Acceptance Test before change
```
=== RUN   TestAccAwsBackupPlan_withLifecycle
=== PAUSE TestAccAwsBackupPlan_withLifecycle
=== RUN   TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
=== PAUSE TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
=== RUN   TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== PAUSE TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== CONT  TestAccAwsBackupPlan_withLifecycle
=== CONT  TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== CONT  TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
--- FAIL: TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly (10.86s)
    testing.go:538: Step 0 error: Error applying: 1 error occurred:
                * aws_backup_plan.test: 1 error occurred:
                * aws_backup_plan.test: error creating Backup Plan: InvalidParameterValueException: Error in rule tf_acc_test_backup_rule_lifecycle_policy_three : Invalid lifecycle. DeleteAfterDays cannot be less than one day
                status code: 400, request id: 757544c3-4628-4a7e-95fa-416098fe2594

--- FAIL: TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly (11.00s)
    testing.go:538: Step 0 error: Error applying: 1 error occurred:
                * aws_backup_plan.test: 1 error occurred:
                * aws_backup_plan.test: error creating Backup Plan: InvalidParameterValueException: Error in rule tf_acc_test_backup_rule_lifecycle_policy_two : Invalid lifecycle. DeleteAfterDays cannot be less than 90 days apart from MoveToColdStorageAfterDays
                status code: 400, request id: e37c0d06-0cd7-4783-b01a-40e1dc5758f0

--- PASS: TestAccAwsBackupPlan_withLifecycle (18.92s)
FAIL
FAIL    github.com/terraform-providers/terraform-provider-aws/aws       18.948s
GNUmakefile:20: recipe for target 'testacc' failed
```

Acceptance Test after change
```
=== RUN   TestAccAwsBackupPlan_withLifecycle
=== PAUSE TestAccAwsBackupPlan_withLifecycle
=== RUN   TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
=== PAUSE TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
=== RUN   TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== PAUSE TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== CONT  TestAccAwsBackupPlan_withLifecycle
=== CONT  TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== CONT  TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
--- PASS: TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly (18.70s)
--- PASS: TestAccAwsBackupPlan_withLifecycle (19.75s)
--- PASS: TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
(20.25s)
PASS
ok      github.com/terraform-providers/terraform-provider-aws/aws
20.266s
```
@dud225
Copy link

dud225 commented Apr 10, 2019

I've been in touch with the support about failures of my backup plans created by TF, here is some useful information I got :

The reason that it is failing is because your lifecycle policy has MoveToColdStorageAfterDays set to 0, whereas it needs to be set to null. The difference may seem trivial, however a value of 0 means that it will try to move the backup to cold storage instantly (which is not allowed), however a value of null means that it will not attempt to move to cold storage at all. The console is not properly setup to reflect this value as it should not be possible to set it to 0, which is why it's hard to catch when only seeing the console output. To have it set to null, 'MoveToColdStorageAfterDays' must be left out completely.

So your command would look like this:
$ aws backup update-backup-plan --backup-plan-id < id > --backup-plan '{"BackupPlanName":"my-backup", "Rules": [{"RuleName": "dailybackups", "TargetBackupVaultName": "my-vault", "Lifecycle": {"DeleteAfterDays": 90}}]}'

In a previous message I was also told the following :

The minimum amount of days that the object can be moved to cold storage is 1 day. The current console enforces this, however the API and an older version of the console does not, so it has been possible to bypass these checks and submit an invalid lifecycle policy.

The parameters for a valid lifecycle policy are:
1. The transition to cold storage must be at least 1 day after backup creation.
2. The backup must remain in cold storage for at least 90 days before expiration.

nywilken added a commit that referenced this issue Apr 10, 2019
…ributes

Closes #8151

Lifecycle policies contain settings for deleting backups, and for moving
them to cold storage. A backup with cold storage enabled can not have a
deletion value lower then 90 days. So to prevent this AWS allows
setting ColdStorageAfter to Never by not setting a value for ColdStorageAfter.

This change adds logic to ensure ColdStorageAfter and DeleteAfter only
get sent within the API request if the values are not empty and greater
than 0.

Acceptance Test before change
```
=== RUN   TestAccAwsBackupPlan_withLifecycle
=== PAUSE TestAccAwsBackupPlan_withLifecycle
=== RUN   TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
=== PAUSE TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
=== RUN   TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== PAUSE TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== CONT  TestAccAwsBackupPlan_withLifecycle
=== CONT  TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== CONT  TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
--- FAIL: TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly (10.86s)
    testing.go:538: Step 0 error: Error applying: 1 error occurred:
                * aws_backup_plan.test: 1 error occurred:
                * aws_backup_plan.test: error creating Backup Plan: InvalidParameterValueException: Error in rule tf_acc_test_backup_rule_lifecycle_policy_three : Invalid lifecycle. DeleteAfterDays cannot be less than one day
                status code: 400, request id: 757544c3-4628-4a7e-95fa-416098fe2594

--- FAIL: TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly (11.00s)
    testing.go:538: Step 0 error: Error applying: 1 error occurred:
                * aws_backup_plan.test: 1 error occurred:
                * aws_backup_plan.test: error creating Backup Plan: InvalidParameterValueException: Error in rule tf_acc_test_backup_rule_lifecycle_policy_two : Invalid lifecycle. DeleteAfterDays cannot be less than 90 days apart from MoveToColdStorageAfterDays
                status code: 400, request id: e37c0d06-0cd7-4783-b01a-40e1dc5758f0

--- PASS: TestAccAwsBackupPlan_withLifecycle (18.92s)
FAIL
FAIL    github.com/terraform-providers/terraform-provider-aws/aws       18.948s
GNUmakefile:20: recipe for target 'testacc' failed
```

Acceptance Test after change
```
=== RUN   TestAccAwsBackupPlan_withLifecycle
=== PAUSE TestAccAwsBackupPlan_withLifecycle
=== RUN   TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
=== PAUSE TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
=== RUN   TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== PAUSE TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== CONT  TestAccAwsBackupPlan_withLifecycle
=== CONT  TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
=== CONT  TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly
--- PASS: TestAccAwsBackupPlan_withLifecycleDeleteAfterOnly (18.70s)
--- PASS: TestAccAwsBackupPlan_withLifecycle (19.75s)
--- PASS: TestAccAwsBackupPlan_withLifecycleColdStorageAfterOnly
(20.25s)
PASS
ok      github.com/terraform-providers/terraform-provider-aws/aws
20.266s
```
@nywilken
Copy link
Contributor

The fix for this issue has bee merged and will release with version 2.6.0 of the Terraform AWS Provider later today.

@bflad bflad added this to the v2.6.0 milestone Apr 11, 2019
@bflad
Copy link
Contributor

bflad commented Apr 11, 2019

This has been released in version 2.6.0 of the Terraform AWS provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.

@ghost
Copy link

ghost commented Mar 30, 2020

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 Mar 30, 2020
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. documentation Introduces or discusses updates to documentation. service/backup Issues and PRs that pertain to the backup service.
Projects
None yet
6 participants